アプリ版:「スタンプのみでお礼する」機能のリリースについて

これはプログラム中のループ内です
=====================
m = IntArray(SIZE); //関数内でmallocを使用

puts("a");   //最後に'a'が表示されて終了

free(m);

puts("b");
=====================

プログラムを実行するとループ内でfree()関数を何度も通るのですが
途中でSegmentation faultが起きて停まります。
free()関数を取り除いても強制終了されます。
この現象の対処法をどなたか教えていただけないでしょうか?

よろしくお願いします。

A 回答 (5件)

>ループを抜けた後


>free()関数の直前に解放する配列の中身を表示してみると異常はありませんでした。

配列の中身を見ても意味はありません。

異常は「配列の外」で起きています。

m[0]~m[SIZE-1]でもなく、tmp[0]~tmp[SIZE-1]でもない、不正なアドレスのメモリにデータを書き込んでいるので「freeした時に破綻」するのです。

この「不正なアドレスのメモリにデータを書き込んでいる」のは、mやtmpを介してアクセスした場合(例えば「tmp[i] = xx」とか「m[j] = xx」とかで、iやjが範囲外)はもちろんですが、全然違う方法でアクセスしている場合もあります。

例えば「strcpy(ptr,"~~~")」で、ptrが「未初期化で不定だった」とか。

なので「原因は確かにループの中にあったが、mにもtmpにも全然まったく関係無い場所だった」などと言う事も起きます。

繰り返しますが、異常は、m[0]~m[SIZE-1]でもなく、tmp[0]~tmp[SIZE-1]でもない、不正なアドレスのメモリにデータを書き込んでいるのが原因です。

いくら、配列mや配列tmpの中身を表示確認したって、何の意味もありません。「メモリが壊れてるのはソコじゃない」のですから。
    • good
    • 0

回答#1の補足を見ずに回答してしまいましたが、



まず、原因と思われるのは、質問者さんのプログラムのうち省略されている
部分ではないかとも考えられます。

そういうこともあるので、
1)IntArray と malloc に置き換える。
2)省略せず、ループ部分はfor分だけとし、提示されたステートメント
  以外は削除する。

というもので、同様の現象になるのか確認してみてはいかがでしょう?

結果
変更してみたら結果OKだった ---> 省略していた部分が原因
変更しても結果は同じ    ---> たぶんmallocに関係した不具合
                 ですが、単純なプログラムなので再現確認は容易
                 になります。
    • good
    • 1
この回答へのお礼

回答して頂いた皆様ありがとうございました。
原因はmain()関数内で配列をコピーするときコピー元がNULLになっていたことでした。
お騒がせしてすみません。

お礼日時:2009/01/31 19:21

http://oshiete1.goo.ne.jp/qa3687298.html
で回答していますが、
「memory over commit」が原因の場合が考えられます。
違うOS上でテストしてみたらどうでしょうか。
上記のQ&Aでのサンプルプログラムでは、
Cygwin上では、強制終了しない。Linux上では強制終了する。
という結果になっていました。
    • good
    • 0

>この現象の対処法をどなたか教えていただけないでしょうか?


プログラムが正しくないので、異常終了しているのですが、
デバッガを使って、Segmentation faultが起こっている場所を特定することができます。(もしくはできる可能性があります)
このような場合、OSとコンパイラを提示したほうが、更に良い回答が得られると思いますよ。

この回答への補足

回答していただいてありがとうございます。
環境は、OS:FreeBSD、コンパイラ:GCC です。
よろしくお願いします。

補足日時:2009/01/30 11:47
    • good
    • 0

>途中でSegmentation faultが起きて停まります。


>free()関数を取り除いても強制終了されます。
であれば、free()を疑うのではなく、そのほかの処理を疑うべき。
「Segmentation fault」はメモリ使用のミスで発生する可能性が高いエラー。
ループ条件のミスや、初期化されていない(不定値の入っている)文字列の利用など、

この回答への補足

回答していただいてありがとうございます。
プログラムを改良したところループを抜けた直後のfree()関数で
Segmentation faultが起きました。
上のプログラムに少し付け加えさせていただきますが、

tmp = IntArray(SIZE);
=====================ループ内
m = IntArray(SIZE); //関数内でmallocを使用

free(m);
=====================ループ終
for(i=0; i<SIZE; i++) printf("%d ", tmp[i]); //中身が異常なく表示される

puts("a");   //最後に'a'が表示されて終了
free(tmp);
puts("b");

ループを抜けた後
free()関数の直前に解放する配列の中身を表示してみると異常はありませんでした。

質問の内容が変わってしまい申し訳ありませんが、よろしくお願いします。

補足日時:2009/01/30 11:39
    • good
    • 0

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