- ベストアンサー
メモリリークのデバッグ
プログラムの実行時にエラーで停止してしまいます。 数値計算系のプログラムで反復計算を行っています。 数万回反復させても大丈夫なのに100万回くらい反復 計算するとプログラムが停止します。 場合によりパソコンがフリーズします。 メモリ関連が原因であることは想像できるのですが デバッグの方法がわかりません。計算の途中にでてくる 関数等でつかわれている変数でmallocしたものは全て 解放しているつもりですがどこかおちがあるのかもしれません。オチがある場合どこを解放しわすれているのか 現在つかめていません。 VCをつかっているのですがデバッガを使って実行途中の メモリの状態を確認する方法など、この問題を解決する 為に有効であると思われる方法をご存じでしたら教えて ください。 windows2000 visualC++6.0professional メモリ256MB
- みんなの回答 (4)
- 専門家の回答
質問者が選んだベストアンサー
ひとことで説明するのは、ちと難しいのですが、VC には、それようの機能が備わっています。 参考URLからたどれるところをじっくりと読んでください。 ある程度大きなプログラムでは、とても有効です。 一連の手順を簡単にまとめると ・ある程度動かしたところで、残っているメモリの一覧を取る ・内容を確認し、解放しているはずかどうかの見当をつける ※この時点で、抜けている解放すべき処理の検討がつくことが多い ・解放しているはずのメモリ領域の割り当て番号を控える ・その番号に対してブレークポイントを設定する ・再度実行する ・スタックとレースをたどれば、割り当てている箇所が分かるので、その領域に対して、適切な解放処理を入れる といった感じの手順の繰り返しになります。
その他の回答 (3)
- aki_m
- ベストアンサー率50% (1/2)
a-kuma様が既に答えられているので蛇足かも知れませんが、 参考までに私の行っているリーク検出の手順を書かせて頂きます。 1:ビルドの種類を「デバッグビルド」に設定。 (コンパイル後のデータが、ワークスペース〔拡張子dsw〕と同フォルダ内の 『Debug』フォルダ内に作成される状態です、デフォルトでこの状態になって いると思います) 2:メモリリークを検出したいプログラムの先頭に、デバッグに必要な ヘッダーファイル「crtdbg.h」をインクルードします。 (複数のソースファイルに渡って調べたい場合は、調べたい全てのソースに インクルードします) 3:プログラムが終了する直前の場所で、メモリリーク検出用の関数 _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF); を呼びます。 4:プログラムをリビルド→実行します。 5:異常終了させずにプログラムを終了させます。 (計算回数を調整する等で対処してみて下さい) 6:アウトプットの「デバッグ」欄に、リークしているメモリサイズが 出力されます。 (例: Detected memory leaks! Dumping objects -> {112} normal block at 0x007D0E10, 4 bytes long. Data: < > CD CD CD CD 3行目は解放されていないメモリのアドレスとそのサイズ、 4行目はその中身です。 *複数のリークがある場合は、その数だけ出力されます。 これはアドレス0x007D0E10から4バイトのメモリが解放されていないよ、 というメッセージです。 中身の「CD」は、リークを検出するためにVCが初期化している値ですので エラーではありません。 ) 更にリーク位置を特定することも出来ますが、余り手順が多すぎても分かり難い と思いますので、とりあえずこの辺りで試してみてはいかがでしょうか。 *位置特定が必要であれば、下手な説明でありますがお答えしたいと思います。
お礼
忙しかった為、返信できませんでした。 大変丁寧な説明ありがとうございます。 手順はだいたいわかったのですが6の表示の意味が わからなくて困っていました。大変参考になります。 ありがとうございました。
- toysmith
- ベストアンサー率37% (570/1525)
作成したアプリケーションの規模にもよりますが、『既に存在するメモリーリークを完全に排除する一般的な手段』はありません。 また、『既に存在するメモリーリークを完全に検出する一般的な手段』はメモリーリーク検出ツールを使う以外にはありません。 ☆ ココで言う『完全』とは「OS、ライブラリ(LIB,DLL,OCXなどを含む)で発生するメモリーリークを含む」と言う意味です。 自作のコード内で発生するメモリーリークのみに着目した場合、#2の方法で検出が可能かと思われます。 しかし、OSやライブラリで発生するメモリーリークに関してはRational Purify(<<高価>>ですが<<効果>>もすごい!)などを使用して検出する以外に『完全な』検出方法はありません。 また、有名な『Windows95のリソースリーク』のように「検出は出来ても修正する手段が存在しない」ということもあるのでご注意ください。
お礼
ご回答ありがとうございます。 メモリリーク検出ツールというものがあるとは知りませんでした。 自作コード内で発生している物と思われる為a-kumaさんの 教えてくださった方法を習得する方向でいきたいと思います。 メモリリーク検出ソフトも調べてみたいと思います。 質問に対する解決が得られたのですが一応もう数日間 締め切らないでおきますのでご了承ください。
- taknt
- ベストアンサー率19% (1556/7783)
メモリリークのチェックをするには、機能を少なくして、それぞれで 確認していくしかないです。 メモリチェックのプログラムはいろいろあると思います。 それで起動時、起動後と確認したらいいでしょう。
お礼
返事が遅くなってしまい大変申し訳ございません。 早速のご回答ありがとうございました。 VCのデバッガを使うにしても機能を少なくすることで バグ取りは楽になるようなのでやってみようとおもいます。 ありがとうございました。
お礼
丁寧なご回答ありがとうございます。 まだヘルプをまだしっかり読めていないのですが 機能がついていると言うことは確認できました。 詳しく読んでいないので不確かですがメモリを確認する為の 関数などが用意されているようですね。 C言語はほぼVCのみで、そのレベルも入門書を一通りできるようにした程度 (現在は自分の知りたいことをMSDNからうまくみつけることができないレベルです・・・)なので MSDNを読んで理解するだけの能力がまだありませんが的確な指示ありがとうございます。