人気マンガがだれでも無料♪電子コミック読み放題!!

UNIX(HP-UX)上でCプログラムを組んでおります。
その際、mallocでセグメンテーションフォルトが起こりました。

mallocでセグメンテーションフォルトが起こった場合、どのように調査するのか、また実際どのような原因で起こりうるのか教えていただけますでしょうか?

このQ&Aに関連する最新のQ&A

A 回答 (3件)

そのようなケースでは、既にその malloc 以前のコードでメモリが


破壊されている事が多いです。

例えば、こんなミスが有るとメモリやスタック等が壊れる可能性大。

・不正なアドレスを解放している、または多重解放している
・バッファ(配列)のオーバーまたはアンダー
・printf や scanf で型指定と引数型が合っていない
 例)printf("%s", int値);
・printf や scanf 等の可変引数呼出で引数の数が合っていない
 例)printf("%d %d", int値);

また、malloc で要求したメモリ量が確保出来なかった場合に、メモリ
不足のエラーではなくセグメンテーションフォルトやアクセス違反等の
エラーが発生した事も有りました。
    • good
    • 0
この回答へのお礼

回答ありがとうございました。
指摘された点を地道に追ってみます。

回答に対する質問なんですが。。。
バッファのアンダーとはどの様な時に発生するのですか?

お礼日時:2004/01/09 17:45

#1です。



>バッファのアンダーとはどの様な時に発生するのですか?
例えば配列をインデックス値ではなくポインタの加減算で参照
している時、更には後方検索などで最後尾から先頭に向かって
ループさせるようなロジックで起こり得ます。

インデックス値がゼロを通り越してマイナスになってしまう
ようなイメージです。
    • good
    • 0
この回答へのお礼

質問への回答ありがとうございます。

なるほど、配列の先頭より前を見てしまうような場合ですね。
アンダーという言葉からイメージが湧かなくて。。。お手数おかけしました。

まだまだ、解決の糸口が見つからないのですが頑張りますね。

お礼日時:2004/01/09 21:05

malloc自体が問題の場合はdmallocというライブラリが


あります。これはmallocをリプレースして、各種検査が
可能になります。HP-UXでも使えます。
http://dmalloc.com/

mallocする前に壊れている場合は、デバッグはマジで
大変なものの1つだと思います(規模にもよりますが)。
ポインタ周りであれば、僕はCのプログラムでもとりあえず
モジュールごとにclassで囲んでC++コンパイラでリンク
してみます。クラスにしてみるとどのコードがだめなのか
判定できますし、コードを1行づつ追うのは精神衛生上
よくないでしょうしね・・

参考URL:http://dmalloc.com/
    • good
    • 0
この回答へのお礼

回答ありがとうございます。
頑張ってdmallocを利用してみます。

angbandさんはC++コンパイラでリンクしてみるとのことですが、C++に手をつけたことのない身としてはそちらの手段は目下の所無理そうです。
教えていただいたことは、もう少し余裕のあるときに試してみますね。

お礼日時:2004/01/09 18:41

このQ&Aに関連する人気のQ&A

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

Qセグメンテーション違反とmalloc

char *name
この宣言でプログラムの組初めはこれでいけたのですが
char *name = (char *)malloc(sizeof(char) * 10);
後からこのようにmallocで動的メモリ確保しないとセグメンテーション違反が起きるようになりました。

なぜこうなるのでしょうか?
それとmallocの使うタイミング(どういう時)に使えばよいのでしょうか?

Aベストアンサー

はなはだ失礼なことを申し上げますが、C言語の基本を理解されていないと思われます。
一般的に変数は、その内容にある値を設定してからでないと、その変数を使用することは、出来ません。これを変数の初期化と言います。
例えば int型の変数 aを確保したとして、これを初期化しないで使用するとどうなるかです。
int a;
として
if (a==10){
printf("aは10です\n");
}else{
printf("aは10ではありません\n");
}
上記のプログラムを実行するとぢうなるでしょうか。
答えは、「どうなるか判らない」です。
たまたま、「aは10です」が表示される場合もありますし、
たまたま、「aは10ではありません」が表示される場合もあります。
これは、int 型の変数aを確保したときに、その内容を初期化していないので、なにが入っているか判らない為にこの状態が発生します。
int型の変数を初期化せずに使った場合は、プログラムがどちらに転ぶか判らないだけですが、ポインター型の変数を値を初期化せずに使用した場合は、事情は異なってきます。
char *name;とした状態では、ポインターnameは初期化されていません。
従って例えば strcpy(name,"abc");
を実行したとすると、ポインターの示す先に、文字列"abc"をコピーします。
では、このポインターの示す先は、いったいどこなのでしょうか。
答えは、「初期化されていないので判らない」です。
とすると、たまたま、コピーしても安全なところを示している場合は、セグメンテーション違反は発生しません。
ところが、たまたま、コピーしてはならないアドレス(OSのみにアクセスが許されるアドレス、例えば0番等)を示していると、セグメンテーション違反になります。
>それとmallocの使うタイミング(どういう時)に使えばよいのでしょうか?
メモリを必要とする時です。この意味が理解できるようになるためには、もう少し、ポインターについて、いろいろとプログラミングをして、ポインターになれることが必要です。

はなはだ失礼なことを申し上げますが、C言語の基本を理解されていないと思われます。
一般的に変数は、その内容にある値を設定してからでないと、その変数を使用することは、出来ません。これを変数の初期化と言います。
例えば int型の変数 aを確保したとして、これを初期化しないで使用するとどうなるかです。
int a;
として
if (a==10){
printf("aは10です\n");
}else{
printf("aは10ではありません\n");
}
上記のプログラムを実行するとぢうなるでしょうか。
答えは、「どうなるか判らない...続きを読む

Qセグメンテーション違反

C言語を使用しています。

構造体に値をいれようとしたら、コンパイルは出来るのですが、実行時に
「セグメンテーション違反です (core dumped)」
となってしまい、それ以上行えません。

構造体と代入したい変数との型は、合っています。

いろいろ本などで見ましたが、何が原因かわからず困っています。
教えてください。
宜しくお願いします。

Aベストアンサー

OSは何でしょうか。コンパイラは何を使用していますか?
通常、デバッグオプションをつけて実行すると、異常の発生したソースの箇所で止まりますので、それが手がかりになります。またNo1の方が言われてますように、ソースが公開できるのであれば、ソースを提示するのが良いかと思います。

QC言語のプログラムが実行できません。

C言語のプログラムが実行できません。

コンパイルは出来るんですが、実行すると、「Segmentation fault」と表示されてしまいます。

これは何のエラーなんでしょうか?
基本的な事かもしれませんが、分かる方宜しくお願い致します。

Aベストアンサー

僕も何度も出したなぁ。

ひとくちにSegmentation faultといっても、それこそさまざまな要因があるので、
これだけで原因を突き止めるのは非常に難しいです。

コンパイルはあくまで文法としてみているだけであり、
処理の流れ、メモリ確保など、プログラムそのものを見ているわけではありません。
このエラーが出るのは文法などよりもっと上位の原因なのです。
たとえばですが。
長さ10の配列があったとして、11番目以降を参照したりすると、
そういうのが出たような気がします。

ですから、変数があれば、その内容をprintf文で逐一出していき、
変な値が入っていないとか、少しずつ直していくしかないと思います。

Qセグメンテーション違反とは??

linuxでC言語のプログラムを構築しています。
gccでコンパイルしたときにセグメンテーション違反という
エラーが出てしまいます。
セグメンテーション違反とは一体なんの
ことなんでしょうか?
メモリのことだと思ってるんですが、原因がよくわかりません。C言語初心者なので
わかりやすく教えて頂けるとありがたいです。

Aベストアンサー

似たような質問を発見しました。以下のURLを参考にしてみてはどうでしょうか?

参考URL:http://oshiete1.goo.ne.jp/kotaeru.php3?q=715484

QC言語 配列の長さの上限

C言語で配列Array[N]の長さNの上限っていくらなんでしょうか?
もし可能なのであれば上限を2147483647にしたいのですが、方法を教えてください。

Aベストアンサー

そもそもWindowsの32bit版はアプリが仮想メモリ空間を2GBしか使えません。2GBを超えるには64bit版が必要です。
たとえ64bit版OSだとしても添え字が2147483647って、単純なintの配列だとしても4x2147483647=8GB必要ですね。実メモリ16GBとかのPCを用意しますか?
そもそも配列で2147483647個必要なアルゴリズムに問題ありだと思います。

QC言語で、メモリを解放しないで終わるプログラム

C言語の話です。

mallocなどで領域を確保したら、解放しなければいけないんですよね。
しかし、解放しないで終了すると具体的にどうなるのか、私は理解していません。

次のような、freeしないプログラムを作って何回か実行してみました。しかし、別におかしくならないですね。


#include <stdio.h>
#include <string.h>
#include <stdlib.h>

char *cp;

int main(void)
{
unsigned int n;

printf("サイズ(2以上)を入力してください:");
scanf("%d",&n);

cp=malloc(n);
if(!cp)
{
printf("%s\n","mallocできませんでした。");
return(1);
}

strcpy(cp,"A");
printf("cpは%sです。\n", cp);

printf("それでは終わりにします\n");

return(0);
}


グローバルでcharの固定長の配列を宣言したとすれば、プログラムの終了時にその領域は解放されると思います。

このような固定長の配列の場合とmallocの場合との違いが問題なんです。

 実験的に、解放しないがために何かおかしくなってしまったり、悪影響を及ぼしたりするようなプログラムを作りたいんですが、どのようにすればよいでしょうか。

もしも私の環境ではそのようなプログラムが作れないなら、別の環境の話でもよいので具体的にこんなふうになってしまうという話をお聞きしたいんです。


過去の質問を検索してみました。
http://oshiete1.goo.ne.jp/kotaeru.php3?q=160037
ここのNo.9では、「freeしないアプリケーションの起動・終了を繰り返すと、リソースが不足する」旨が書かれていて、質問者の方もそれで納得されているようです。
しかし、私は、リソースが不足するとはどういうことで、何が起こるのか、知りません。

私のマシン
OS:Windows98SE
VC++6.0

C言語の話です。

mallocなどで領域を確保したら、解放しなければいけないんですよね。
しかし、解放しないで終了すると具体的にどうなるのか、私は理解していません。

次のような、freeしないプログラムを作って何回か実行してみました。しかし、別におかしくならないですね。


#include <stdio.h>
#include <string.h>
#include <stdlib.h>

char *cp;

int main(void)
{
unsigned int n;

printf("サイズ(2以上)を入力してください:");
scanf("%d",&n);

cp=malloc(n);
if(!cp)
{...続きを読む

Aベストアンサー

書き忘れましたのでもう一度。

malloc/freeを1セットで考えている人がいるようですが、「プログラム終了時にすべてをfreeする」なんていう処理は愚の骨頂です。

malloc/freeはマンションの内装工事のようなものです。
mallocは次の入居者のために内装工事を行います。
freeは次の入居者のための回復工事です。
マンション自体の取り壊し(=プログラムの終了)が行われる寸前に回復工事の必要はありません。

動的メモリ領域を10000個くらい確保して、freeして終了する場合とfreeせずに終了する場合を比べてみてください。
プログラム終了寸前にfreeするのは無駄以外の何者でもありません。

Qメモリのセグメント違反の解決方法を教えてください。

こんにちわ,
現在プログラムを作成しているのですが,Segmentation Faultが出て困っています。

そのセグメント違反が出ているのがmallocの中(PCインナーの関数)で普通ならmallocの返り値がNULLかそれ以外かということになりますが,それ自体も中でセグメント違反が起こるので帰ってきません。

MALLOC_CHECK_=1によってその触っているポインターを見ると,
free(): invalid pointer 0x93c5380!
free(): invalid pointer 0x93c5c18!
とでるので,おそらくmallocのなかで必要なくなったポインターをフリーをしていると考えられるのですが,
gdbのwatchpointでそのアドレスを指定してみてみると,メインに入る前にそのポインタ自体をいじっている関数も内部的な関数みたいでどこをなおすとセグメント違反が直るのかわかりません。

このようなメモリ問題がおきたときどのようなツールや解決法があるのでしょうか。

よろしくお願いします。

Aベストアンサー

> このようなメモリ問題がおきたときどのようなツールや解決法があるのでしょうか。

このようなメモリ問題は起こしてはいけません。いや、冗談ではなく、本当に。
プログラムの、全然関係の無い場所で破壊が起きていたら、突き止めるのは非常に
困難です。追跡するとしたら、malloc()とfree()の呼び出しの都度、その情報を
吐き出して、後で対照させてみるといったところでしょうか。

重要なのは予防です。とりあえず、心がけることとしては、
・グローバル変数を多用しない。特に、ポインタはグローバル変数にしない。
・自動変数(内部変数)のアドレスを外部に持ち出さない。
・free()したポインタ変数は、すぐにNULLで初期化しておく。
あたりでしょうか。

すみません。ツールはあるかもしれませんが、知りません。

Qint型からchar型への変換

タイトル通り、int型からchar型への変換の仕方がわかりません!><
どうしたらいいのでしょうか?

Aベストアンサー

#include <stdio.h>


char buf[5];
int no;

no = 10;
sprintf(buf, "%d", no);

Qfgetsで拾われる改行文字を削除したい

お世話になります

 C言語初心者のものです。今課題でC言語を用いたプログラミングを
Fedora上でやっています。問題は、fgetsでテキストファイルから、取得
した文字列の中から改行文字を削除できないことです。文字変数のアド
レスはわかっているのですが、終端文字に置換しようとすると、セグメ
ントエラーになってしまいます。これは如何にして解決すべきでしょう
か。よろしくお願いします。

Aベストアンサー

ポインタとかアドレスとか、C言語の用語としてあるものを別の意味に使うとまぎらわしいです。

「ポインタ」「アドレス」と言われたら、 この例なら str, str+i が思い浮びます。
「文字変数のアドレス」だと
char c ;
に対しての
&c
が思い浮びます。

配列なら「添字」、意味的には「x文字目」ですね。

> for(i=0;;i++){
> if(*(str+i)=='/n') {
> *(str+i)='\0';
> break;
> }
> }
/nが\nの間違いなら、この方法で半分正解です。もう少し広い範囲(可能なら全体)で見ないことにはなんとも言えません。
fgetsが最大文字数に達したり、ファイルの最後になったりで、strに改行文字が含まれない場合には、このループは止まりません(Segmentension Falutになって止まる)

・そのような状態になってないか、予めチェックする
・ループを終了させる仕組みを用意しておく
: forの終了条件を記述する、for中で if(*(str+i)=='\0') { break;} 等としておく、等
といった対策が必要です。


あと細かいところを言えば
・strを配列で用意したなら *(s+i)じゃなくてs[i]でいいんじゃないかな
・あるいは char *pみたいにしておいて、 iのループでなく pでループを組む( for(p=str;*p!='\0';p++) )とか。

ポインタとかアドレスとか、C言語の用語としてあるものを別の意味に使うとまぎらわしいです。

「ポインタ」「アドレス」と言われたら、 この例なら str, str+i が思い浮びます。
「文字変数のアドレス」だと
char c ;
に対しての
&c
が思い浮びます。

配列なら「添字」、意味的には「x文字目」ですね。

> for(i=0;;i++){
> if(*(str+i)=='/n') {
> *(str+i)='\0';
> break;
> }
> }
/nが\nの間違いなら、この方法で半分正解です。もう少し広い範囲(可能なら全体)で見ないことにはなんとも言えません。
fgetsが...続きを読む

QSegmentation Fault (メモリ制限?)

Segmentation Fault (Fortranのプログラム)に関して質問です。


あるデータを処理するプログラムですが、小さなデータの場合問題ないですが、
大きなデータを扱うようになった場合Segmentation Faultとなります。

宣言している配列サイズを超えた部分のアクセスなどでSegmentation
Faultが出ることがあるようですが、どうやらそのような現象ではなく、
メモリ制限にひっかかっている感じがいたします。


エラーが出る部分はどうやらSubroutine内の大きなデータ宣言を
している部分のようです。(下の例ではtest bが表示れる以前に止まります。)

!--------------------------------------------------
subroutine calc_tri( )

implicit none

real*8 data1(3,200000) !<--- ここでエラー -->

write(6,*) 'test b'
!--------------------------------------------------


このような場合、配列データを減らす以外にどのような対策が
あるのでしょうか?
あるいはメモリ制限になりそうなデータ数が分る方法などあります
でしょうか?


環境は
linux (CentOS)
intel Fortran Compiler version 8.0
Mem: 1GB

topコマンドにて Memの使用割り合いは10%にもならないのですが
コンパイラによるメモリ制限などもあるのでしょうか?

subroutine内の配列の宣言はデータ数より多くとっていることは確認しています。

Segmentation Fault (Fortranのプログラム)に関して質問です。


あるデータを処理するプログラムですが、小さなデータの場合問題ないですが、
大きなデータを扱うようになった場合Segmentation Faultとなります。

宣言している配列サイズを超えた部分のアクセスなどでSegmentation
Faultが出ることがあるようですが、どうやらそのような現象ではなく、
メモリ制限にひっかかっている感じがいたします。


エラーが出る部分はどうやらSubroutine内の大きなデータ宣言を
している部分のようです。(下...続きを読む

Aベストアンサー

スタックオーバフローを起こしているのでは。
ulimitとかでスタックサイズを引き上げるか、ALLOCATABLEな配列にしてヒープ領域を使うようにするとか。


このQ&Aを見た人がよく見るQ&A

人気Q&Aランキング