_CrtDumpMemoryLeaks()の役割


CrtDumpMemoryLeaks()は、現在のメモリリークを表示します.「現在」であることに注意してください.つまり、実行すると、破棄されていないすべてのオブジェクトがメモリ漏れを報告します.そのため、できるだけこの文をプログラムの最後に実行させます.
漏れが検出された場所を反映しています.MFCでは比較的正確に使用され、InitInstanceで呼び出されます.CrtDumpMemoryLeaks.
C++メモリの割り当てと解放はすべてユーザーコードが自分で制御して、柔軟なメカニズムはパンドラの箱のようで、つまりプログラマーにもっと広く発揮させました
空間は、代々伝わるメモリ漏れの問題も発生しています.初心者にとって、最もよく犯すエラーはnewがオブジェクトを出して解放することを忘れていることです.一般的な小さなアプリケーションにとって、メモリスペースは何でもありません.しかし、メモリ漏洩の問題が24時間かかるプラットフォームクラスのプログラムに発生すると、システムの使用可能なメモリが急速に減少し、最後にシステムリソースが消費され、システムがクラッシュします.
メモリの漏洩を防止し、チェックする方法を学ぶことは、合格したc++プログラマーが備えなければならない能力です.しかし、メモリ漏洩はプログラムが実行され、一定の条件を満たす場合に発生するため、直接コードから漏洩原因を検出するのは難しい.また、メモリ漏洩がマルチスレッドプログラムで発生すると、大量のコードの中から人工的に漏洩原因を探し出す必要があり、新人にとってもベテランにとっても悪夢である.
本文はVS 2003の中でメモリの漏れを検査する方法を紹介して、各位の新人のベテランの参考に供して、VC 6の中でいくつかの変動を実現して、詳細は自分で関連資料を参照することができます.
ポリシー分析の確認
まず、24時間実行するプラットフォームプログラムのメモリ漏洩状況を検出する必要があると仮定し、具体的なメモリ漏洩速度を決定することはできませんが、プログラムが一定時間(例えば10分)漏洩したメモリ量がL(eak)に近いと判断することができます.
10分間の実行時間内にプログラムが新しく申請したメモリA(lloc)を考慮すると、このメモリにはプログラムが正常に申請し、後続の実行中に解放される通常のメモリブロックN(ormal)と漏洩したメモリL、すなわちA=N+Lが含まれている.
後続の運転では、N部分の申請と解放が絶えないため、この部分の総量は基本的に変わらないが、L部分は申請のみで解放されないため、占有メモリの総量はますます大きくなる.
この結果を実行時間軸に配置し、プログラムの実行中の20分間を観察し、メモリ漏れ速度をdL/10分と仮定し、時間軸は以下の通りである.
----------------|--------------------|-------------------|----------------------------
              Tn-2 Tn-1 Tn

3点間隔はいずれも10分で、以下の結論があります.
Tn点の合計メモリ割当量An=N+dL*n,Nは通常の割当メモリ,dL*nはメモリリーク量の合計,Tn-1点の合計メモリはAn-1=N+dL*(n-1)である.ここでは、解放されたメモリ量は考慮されず、増加したメモリ量のみが考慮されます.従って,単位時間当たりのメモリリーク量dL=An−An−1が明らかになった.
メモリDumpファイルを生成するコード実装
このようなポリシーを完了するには、まずメモリブロックの割り当てと解放状況を追跡し、実行時に割り当て状況をファイルに保存して比較分析する必要があります.幸いなことに、m$はメモリ追跡を容易にするための一連の手段を提供しています.具体的な実装手順は次のとおりです.
メモリトラッキングに必要なライブラリを含める
StdAfxでhに次のコードを追加します.マクロを定義する必要があります.CRTDBG_MAP_ALLOC、そうでない場合、後続のdumpファイルにメモリブロックのコード位置が欠けます.
#ifdef _DEBUG
              //for memory leak check
              #define _CRTDBG_MAP_ALLOC //      dump              
              #include
              #include
              #endif

メモリトラッキングの開始
上記の手順が完了すると、アプリケーションの起動時に次のコードを追加してメモリトラッキングを起動し、起動後にメモリの割り当てと解放状況を自動的に検出し、結果の出力を許可することができます.
//enable leak check
              _CrtSetDbgFlag( _CRTDBG_REPORT_FLAG);

結果出力をdumpファイルに向ける
デフォルトでは、メモリ漏洩のdumpコンテンツはvsのdebug出力ウィンドウに出力されるが、サービスクラスプログラムではvsのdebugモードでメモリ漏洩を追跡することはできないため、dumpコンテンツの出力をdumpファイルに転送する必要がある.プログラムに次のセクションを追加します.
HANDLE hLogFile;//        
              hLogFile = CreateFile("./log/memleak.log", GENERIC_WRITE, FILE_SHARE_WRITE|FILE_SHARE_READ,
              NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);//      
              _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE);// warn           (  dump 
                    warning)
              _CrtSetReportFile(_CRT_WARN, hLogFile);//               

メモリDumpの保存
以上の設定が完了すると、プログラムに次のコードを追加し、メモリdumpを指定したdumpファイルに出力できます.
_CrtMemState s1, s2, s3;//  3       
              ......
              _CrtDumpMemoryLeaks();//Dump            ,          ,   An
              //       ,            
              _CrtMemCheckpoint( &s2 );
              if ( _CrtMemDifference( &s3, &s1, &s2) )
              {
              _CrtMemDumpStatistics( &s3 );//dump            
              //for next compare
              _CrtMemCheckpoint( &s1 );
              }
              time_t now = time(0);
              struct tm *nowTime = localtime(&now);
              _RPT4(_CRT_WARN,"%02d %02d:%02d:%02d snapshot dump.
",               nowTime->tm_mday, nowTime->tm_hour,nowTime->tm_min,nowTime->tm_sec);// dump

以上のコードは、1つの関数においてタイマによって定期的にトリガーされるか、手動snapshotによって等しい期間のメモリdumpを生成することが望ましい.
dumpファイルの内容の例は次のとおりです.
Detected memory leaks!
              Dumping objects ->
              {20575884} normal block at 0x05C4C490, 87 bytes long.
              Data: 02 00 1D 90 84 9F A6 89 00 00 00 00 00 00 00 00
              ...
              d:\xxxxx\xxxworker.cpp(903) : {20575705} normal block at 0x05D3EF90, 256 bytes long.
              Data: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
              ...
              Object dump complete.
              0 bytes in 0 Free Blocks.
              215968 bytes in 876 Normal Blocks.
              0 bytes in 0 CRT Blocks.
              0 bytes in 0 Ignore Blocks.
              0 bytes in 0 Client Blocks.
              Largest number used: 220044 bytes.
              Total allocations: 7838322 bytes.
              10 16:29:14 snapshot dump.

上の赤い部分は、ユーザコードに割り当てられて解放されていないメモリブロックの位置です.
解析Dumpファイル
先にdumpファイルで各時点のメモリdumpを取得しましたが、前述の分析戦略により、n回目のdumpのメモリブロック割当状況Anをn-1回目のdumpのメモリブロック割当状況An-1と比較するだけで、メモリリークが発生した位置に位置決めできます.dumpファイルは一般的に容量が大きいため、*人工的に比較することはほとんど不可能であるため、比較の考え方を紹介するだけで、皆さんは自分で小道具を作って処理する必要があります.
1.隣接する2つの時点のdumpファイルD 1,D 2を抽出し、D 1をD 2以前のdumpとする
2.dumpファイルからユーザコードが割り当てられたメモリブロック(すなわち、明確なコード位置を有し、かつnormal blockであるメモリブロック)をそれぞれ抽出し、メモリブロックID(例えば、「d:xxxxxxxworker.cpp(903):{20575705}」赤色部分)に基づいてリストL 1およびL 2にそれぞれ保存する
3、リストL 2を遍歴し、L 1に現れたことのないメモリブロックを記録する.
4、3の結果によると、メモリの割り当てコードの位置によって、各所のコード漏れのメモリブロック数を統計し、降順に並べ、割り当て回数が多いコードほど、メモリ漏れの可能性が高い.