- ベストアンサー
メモリのセグメント違反の解決方法を教えてください。
こんにちわ, 現在プログラムを作成しているのですが,Segmentation Faultが出て困っています。 そのセグメント違反が出ているのがmallocの中(PCインナーの関数)で普通ならmallocの返り値がNULLかそれ以外かということになりますが,それ自体も中でセグメント違反が起こるので帰ってきません。 MALLOC_CHECK_=1によってその触っているポインターを見ると, free(): invalid pointer 0x93c5380! free(): invalid pointer 0x93c5c18! とでるので,おそらくmallocのなかで必要なくなったポインターをフリーをしていると考えられるのですが, gdbのwatchpointでそのアドレスを指定してみてみると,メインに入る前にそのポインタ自体をいじっている関数も内部的な関数みたいでどこをなおすとセグメント違反が直るのかわかりません。 このようなメモリ問題がおきたときどのようなツールや解決法があるのでしょうか。 よろしくお願いします。
- みんなの回答 (4)
- 専門家の回答
質問者が選んだベストアンサー
> このようなメモリ問題がおきたときどのようなツールや解決法があるのでしょうか。 このようなメモリ問題は起こしてはいけません。いや、冗談ではなく、本当に。 プログラムの、全然関係の無い場所で破壊が起きていたら、突き止めるのは非常に 困難です。追跡するとしたら、malloc()とfree()の呼び出しの都度、その情報を 吐き出して、後で対照させてみるといったところでしょうか。 重要なのは予防です。とりあえず、心がけることとしては、 ・グローバル変数を多用しない。特に、ポインタはグローバル変数にしない。 ・自動変数(内部変数)のアドレスを外部に持ち出さない。 ・free()したポインタ変数は、すぐにNULLで初期化しておく。 あたりでしょうか。 すみません。ツールはあるかもしれませんが、知りません。
その他の回答 (3)
- tatsu99
- ベストアンサー率52% (391/751)
ParaSoft社からInsure++がでています。 以下は、Insure++の概要です。 ------------------------------------ Insure++は、C/C++アプリケーションのランタイムエラーを自動的に検出する開発支援ツールです。メモリ破壊、メモリリーク、ポインターエラー、I/Oエラーといっ たC/C++特有の検出困難なエラーをプログラムコンパイル時と実行時に自動的に検出し、ファイル名、行番号、ソースコードなど、プログラムの修正に役立つ情報を的確にレポートします。また、そのレポートからソースコードにジャンプし、その場でエラーを修正することも可能です。さらに、TCAやInuseを使用することにより、カバレッジ分析、メモリ使用分析も可能です。Insure++を使用することにより、高品質なソフトウェアを迅速かつ容易に開発できます。 ------------------------------------------- 私は、これを使用した経験はありませんので、今回の問題の解決に有効であるとは、言い切れませんが、試してみる価値はあると思います。 現在 LINUX用の体験版(20日間有効)が無償で提供されていますので、それを利用されてはいかがでしょうか。
- BILLY-J
- ベストアンサー率57% (60/105)
#1さんや#2さんが仰るように、メモリ周りを壊すとタチが悪い 挙動になってしまいます。 一撃でトドメを刺してくれるようなメモリ破壊なら一目瞭然ですが、 ボディーブローのように内面を静かに壊して行くパターンも多々有り 厄介です。 後者の場合、全然関係無いタイミングで落ちます。多いのは関数から リーターンする等スタックが動くタイミングですが、正しいポインタ の free や realloc 等の「それらしい」場所で反応する場合も有る から始末に悪いです。 先に答えた方の復唱になってしまいますが、取り敢えず free して いる箇所を全て free(ptr); ↓ if (ptr != NULL) { free(ptr); ptr = NULL; } に置き換えてみて下さい。 変数 ptr 定義部での初期化もお忘れ無く。 例えば char *ptr = NULL; これで2重 free の罠からは脱出できます。
そういう場合は、大抵他のところに問題があります。 一番考えられるのはメモリの二重 free です。 次に考えられるのはメモリ破壊です。 確保した領域を前か後ろにはみ出して使用していることが考えられます。 その観点でプログラムをチェックしてみてください。