• ベストアンサー

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

こんにちわ, 現在プログラムを作成しているのですが,Segmentation Faultが出て困っています。 そのセグメント違反が出ているのがmallocの中(PCインナーの関数)で普通ならmallocの返り値がNULLかそれ以外かということになりますが,それ自体も中でセグメント違反が起こるので帰ってきません。 MALLOC_CHECK_=1によってその触っているポインターを見ると, free(): invalid pointer 0x93c5380! free(): invalid pointer 0x93c5c18! とでるので,おそらくmallocのなかで必要なくなったポインターをフリーをしていると考えられるのですが, gdbのwatchpointでそのアドレスを指定してみてみると,メインに入る前にそのポインタ自体をいじっている関数も内部的な関数みたいでどこをなおすとセグメント違反が直るのかわかりません。 このようなメモリ問題がおきたときどのようなツールや解決法があるのでしょうか。 よろしくお願いします。

質問者が選んだベストアンサー

  • ベストアンサー
  • ranx
  • ベストアンサー率24% (357/1463)
回答No.2

> このようなメモリ問題がおきたときどのようなツールや解決法があるのでしょうか。 このようなメモリ問題は起こしてはいけません。いや、冗談ではなく、本当に。 プログラムの、全然関係の無い場所で破壊が起きていたら、突き止めるのは非常に 困難です。追跡するとしたら、malloc()とfree()の呼び出しの都度、その情報を 吐き出して、後で対照させてみるといったところでしょうか。 重要なのは予防です。とりあえず、心がけることとしては、 ・グローバル変数を多用しない。特に、ポインタはグローバル変数にしない。 ・自動変数(内部変数)のアドレスを外部に持ち出さない。 ・free()したポインタ変数は、すぐにNULLで初期化しておく。 あたりでしょうか。 すみません。ツールはあるかもしれませんが、知りません。

その他の回答 (3)

  • tatsu99
  • ベストアンサー率52% (391/751)
回答No.4

ParaSoft社からInsure++がでています。 以下は、Insure++の概要です。 ------------------------------------ Insure++は、C/C++アプリケーションのランタイムエラーを自動的に検出する開発支援ツールです。メモリ破壊、メモリリーク、ポインターエラー、I/Oエラーといっ たC/C++特有の検出困難なエラーをプログラムコンパイル時と実行時に自動的に検出し、ファイル名、行番号、ソースコードなど、プログラムの修正に役立つ情報を的確にレポートします。また、そのレポートからソースコードにジャンプし、その場でエラーを修正することも可能です。さらに、TCAやInuseを使用することにより、カバレッジ分析、メモリ使用分析も可能です。Insure++を使用することにより、高品質なソフトウェアを迅速かつ容易に開発できます。 ------------------------------------------- 私は、これを使用した経験はありませんので、今回の問題の解決に有効であるとは、言い切れませんが、試してみる価値はあると思います。 現在 LINUX用の体験版(20日間有効)が無償で提供されていますので、それを利用されてはいかがでしょうか。

参考URL:
https://www.techmatrix.co.jp/asq/insure/index.html
  • BILLY-J
  • ベストアンサー率57% (60/105)
回答No.3

#1さんや#2さんが仰るように、メモリ周りを壊すとタチが悪い 挙動になってしまいます。 一撃でトドメを刺してくれるようなメモリ破壊なら一目瞭然ですが、 ボディーブローのように内面を静かに壊して行くパターンも多々有り 厄介です。 後者の場合、全然関係無いタイミングで落ちます。多いのは関数から リーターンする等スタックが動くタイミングですが、正しいポインタ の free や realloc 等の「それらしい」場所で反応する場合も有る から始末に悪いです。 先に答えた方の復唱になってしまいますが、取り敢えず free して いる箇所を全て free(ptr);   ↓ if (ptr != NULL) {   free(ptr);   ptr = NULL; } に置き換えてみて下さい。 変数 ptr 定義部での初期化もお忘れ無く。 例えば char *ptr = NULL; これで2重 free の罠からは脱出できます。

noname#6581
noname#6581
回答No.1

そういう場合は、大抵他のところに問題があります。 一番考えられるのはメモリの二重 free です。 次に考えられるのはメモリ破壊です。 確保した領域を前か後ろにはみ出して使用していることが考えられます。 その観点でプログラムをチェックしてみてください。

関連するQ&A

  • 構造体へのポインタの動的確保について

    構造体へのポインタを動的確保しようとmalloc関数を使用すると segmentation faultが起きます。 typedef struct cell{ char *word; int count; struct cell *next; }node_t; という構造体で node_t *ptr=(node_t*)malloc(sizeof(node_t)*num); という風に動的確保しようとするとsegmentation faultが起きました。 gdbを使って調べると Starting program: /home/programII/week05/a.out file1 file2 Program received signal SIGSEGV, Segmentation fault. 0x00007ffff7b4ce36 in ?? () from /lib/x86_64-linux-gnu/libc.so.6 というメッセージが返ってきます。 これはライブラリとのリンクが正しく行われていないということでしょうか? しかし、ポインタの動的確保以外でmalloc関数を使用すると 正常に動作するのでライブラリ自体が無いわけではないようです。 ptr[2]といった風にポインタを参照したいのですが上手くいきません。 よろしくお願いします。

  • メモリ破壊で困っています。

    学生です。 現在、cの課題プログラムを作成していて、メモリ破壊と思われる現象で困っています。具体的には、 mallocである構造体へのポインタの3次元配列を確保したはずのものが(malloc時にNULLは返ってきていない)、その後、関係のない関数を呼んだ瞬間にその配列の値が書き換えられている。もしくはアクセスできなくなるといった状況です。 gdbで調べてみたところメモリを確保してから破壊されるまでにfreeはしていません。「関数を呼んだ瞬間に」値が変わるというのは原因がまったくわかりません。 どなたか心当たりある方、ぜひともアドバイスをよろしくお願いします。

  • (int *)の意味

    しょーもない質問すみません。 C++を独学中のプログラミング自体初学者です。 今読んでる教科書に、malloc関数の説明として、 指定された大きさの領域をヒープに割り当て、その領域の先頭のポインタを返す関数であるとあり、 例には、 .... int *x; x=(int *)malloc(sizeof(int)); *x=100; ..... などとあるのですが、malloc関数の前の(int *)は xはあくまで変数、malloc関数で帰ってくるのはpointerなので、 *でポインタから変数にした上で、その変数の型をintに強制的にしているという理解で合っているでしょうか?? どうも*がついている分、xはポインタのような気もして、混乱しています。

  • free()関数の多用 と Segmentation fault

    これはプログラム中のループ内です ===================== m = IntArray(SIZE); //関数内でmallocを使用 … puts("a");   //最後に'a'が表示されて終了 free(m); puts("b"); ===================== プログラムを実行するとループ内でfree()関数を何度も通るのですが 途中でSegmentation faultが起きて停まります。 free()関数を取り除いても強制終了されます。 この現象の対処法をどなたか教えていただけないでしょうか? よろしくお願いします。

  • メモリの解放free

    double **w; int no;    | if((w = (double *)malloc(sizeof(double)*no))==NULL){ printf("Memory Error1"); exit(1); }    |  データ格納処理    | free(w); のようなプログラムの中で、 データ格納処理の途中でSegmentation faultで 落ちてしまいました。この場合、freeが実行されなくても メモリは解放してくれるのでしょうか? また、mallocでメモリ確保できたはずなのに 存在するはずの場所にデータを格納できない原因として 考えられるものはなんでしょうか? ちなみに、落ちる場所が実行の度に変わっているようで、 同じ条件なのにデータの格納数が違っています。

  • C言語 ポインタの課題について

    プログラミング初心者です プログラミングの課題でI 番目のポケモンを得る 関数get_pokemonを実装し返り値の値は*charとする という課題が出たのですが画像の通りに書いた結果 segmentation faultというエラー文が出てきました 良ければこのエラーが出てきた理由とどうすればちゃんと表示されるか教えてくれると助かります。

  • C言語、配列、動的にメモリを割り当て

    すみません。お助けください。 動的なメモリの割り当てによって配列を複数作るときに、メモリを割り当てるルーチンを外部関数化したいのですが、うまくいきません。 具体的にはつぎのような感じです。 b[2] に 値を代入するときに Segmentation fault(core dumped) になってしまいます。 正しくは、どのようにすればよいのでしょうか。 よろしくお願いたします。 main() { int n=5; double *a, *b; mymalloc( a, n ); mymalloc( b, n ); a[2] = 3.5; printf( "%f\n", a[2] ); b[2] = 4.4; printf( "%f\n", b[2] ); } int mymalloc(double *c, int n) { c = (double *)malloc( n * sizeof(double)); }

  • 関数宣言

    3次元で領域を確保するプログラムをmalloc関数を用いて書きました。しかし、プログラムが長いので関数宣言をしなさいといわれたために、以下のプログラムを書きました。しかし、途中でつまづいてしまい、どのように関数を用いたり、関数を定義すれば良いのか混乱しています。初心者ですが、どうかお願いします。 /*ソース*/ #include<stdio.h> #include<stdlib.h> int main(){ double ***C; f3Malloc(C,.,.); //数値を代入(関数の使い方?) f3Free(C,.,.); } /*3次元配列(返し方?)*/ double*** f3Malloc(C,,){ int i,j,x,y,z; x = 2; y = 3; z = 4; C=(double***)malloc(sizeof(double**)*x*y*z); for(i=0;i<y;i++){ C[i]=(double**)malloc(sizeof(double*)*y*z); for(j=0;j<z;j++){ C[i][j]=(double*)malloc(sizeof(double)*z); } } } /*メモリの解放(返し方?)*/ void f3Free(C,.,.){ int i,j,x,y; x = 2; y = 3; for(i=0;i<x;i++){ for(j=0;j<y;j++){ free(C[i][j]); } free(C[i]); } free(C); }

  • C言語:関数の返り値と引数について

    C言語:関数の返り値と引数について C言語の関数を作るとき、ほしい値とかを引数にして渡す場合と、そのまま返り値で渡す場合の二種類がありますよね? 例えば、 ・void Smooth( Image *src, Image *dst, int param ); ・Image *Smooth( Image *src, int param ); みたいな感じで mallocとかは返り値で渡してますけど、opencvの関数(例えばcvSmooth)とかは引数にしてます これって使い分けとかあるんでしょうか?

  • mallocでメモリーを確保しようとすると暴走します

     組み込み系のプログラミングをやっているもので、malloc、freeを使って動的にメモリーの確保、開放を行っているのですが、途中で暴走してしまいます。 (mallocを呼び出すと、返ってこなくなります。)    そこでmallocの動作を見ようと、以下のプログラムを作って動作させると、while文の中を一周はするのですが、2週目のp2のポインターの値が返ってきません。(malloc関数の中でloopしています。)     /* 以下ソースコード */  char *p1;  char *p2;  char *p3;  char *p4;  while(1){    p1 = (char*)malloc(100);    p2 = (char*)malloc(100);    p3 = (char*)malloc(100);    free(p3);    p4 = (char*)malloc(100);    free(p4);    free(p2);    free(p1);  }  ※メモリーは、2k確保していあるので、サイズがオーバーしているということはないと思います。  ご質問ですが、  ・上記ソースコードで暴走するような要因がありますでしょうか?  ・malloc、free関数でメモリーの取得、開放の順番など注意しないといけないことがあるのでしょうか?  ・malloc、free関数等を自作とかされていますでしょうか?  どうぞよろしくお願い致します。

専門家に質問してみよう