C++メモリリークチェック
説明、私が使っているideはvs 2008です
1.工事をdebugに設定
メモリ漏洩の検出は一般的にdebugモードで行われる
2.メモリリークを確認する必要があるcppヘッダに
3.コードにこんな言葉を挿入する
EnableMemLeakCheck();
4.出力で漏れを見ることができます
例を挙げると、例ではnewExで表す上記マクロ定義のnew
出力に表示される内容(debugでプログラムを実行し、フォークでプログラムを閉じます)
memory leaks! Dumping objects -> e:\project\test\test_mem_leak\test_mem_leak\test_mem_leak.cpp(101) : {124} normal block at 0x00295CB8, 400 bytes long. Data: < > CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD e:\project\test\test_mem_leak\test_mem_leak\test_mem_leak.cpp(92) : {122} normal block at 0x00294C30, 9 bytes long. Data: < > CD CD CD CD CD CD CD CD CD e:\project\test\test_mem_leak\test_mem_leak\test_mem_leak.cpp(92) : {121} normal block at 0x00294BE8, 8 bytes long. Data: < > CD CD CD CD CD CD CD CD e:\project\test\test_mem_leak\test_mem_leak\test_mem_leak.cpp(92) : {120} normal block at 0x00299F88, 7 bytes long. Data: < > CD CD CD CD CD CD CD e:\project\test\test_mem_leak\test_mem_leak\test_mem_leak.cpp(92) : {119} normal block at 0x00299F40, 6 bytes long. Data: < > CD CD CD CD CD CD e:\project\test\test_mem_leak\test_mem_leak\test_mem_leak.cpp(92) : {118} normal block at 0x00299EF8, 5 bytes long. Data: < > CD CD CD CD CD e:\project\test\test_mem_leak\test_mem_leak\test_mem_leak.cpp(92) : {117} normal block at 0x00299EB8, 4 bytes long. Data: < > CD CD CD CD e:\project\test\test_mem_leak\test_mem_leak\test_mem_leak.cpp(92) : {116} normal block at 0x00299E78, 3 bytes long. Data: < > CD CD CD e:\project\test\test_mem_leak\test_mem_leak\test_mem_leak.cpp(92) : {115} normal block at 0x00299E38, 2 bytes long. Data: < > CD CD e:\project\test\test_mem_leak\test_mem_leak\test_mem_leak.cpp(92) : {114} normal block at 0x00299DF8, 1 bytes long. Data: < > CD e:\project\test\test_mem_leak\test_mem_leak\test_mem_leak.cpp(92) : {113} normal block at 0x00299DB8, 0 bytes long. Data:<>励p e:projecttesttest_mem_leak\test_mem_leak\test_mem_leak.cpp(88) : {112} normal block at 0x00299D50, 40 bytes long. Data: <0L) > 30 4C 29 00 CD CD CD CD CD CD CD CD CD CD CD CD Object dump complete.
書類名と行番号があり、先に申請してから釈放します.
拡張:
実際には別のnewを使用するdbgnew.cppでは、次の例を示します.
注意、const char*szFileNameは使用できます_file__カスタムクラスを使用してchar*に再ロードすることもできます(老馬のコード提供に感謝します)
例:
もちろん、char*ポインタを関数で返すこともできます
これでカスタムコンテンツを返すことができます.今回の戻りには構造時のシーケンス番号が付けられており、もちろん時間などを追加することもできます.結果は次のとおりです.
e:\project\test\test_mem_leak\test_mem_leak\test_mem_leak.cpp(95) : 11 (95) : {123} normal block at 0x002B4C78, 400 bytes long. Data: < > CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD e:\project\test\test_mem_leak\test_mem_leak\test_mem_leak.cpp(92) : 10 (92) : {122} normal block at 0x002B4C30, 9 bytes long. Data: < > CD CD CD CD CD CD CD CD CD e:\project\test\test_mem_leak\test_mem_leak\test_mem_leak.cpp(92) : 9 (92) : {121} normal block at 0x002B4BE8, 8 bytes long. Data: < > CD CD CD CD CD CD CD CD e:\project\test\test_mem_leak\test_mem_leak\test_mem_leak.cpp(92) : 8 (92) : {120} normal block at 0x002B9F88, 7 bytes long. Data: < > CD CD CD CD CD CD CD e:\project\test\test_mem_leak\test_mem_leak\test_mem_leak.cpp(92) : 7 (92) : {119} normal block at 0x002B9F40, 6 bytes long. Data: < > CD CD CD CD CD CD e:\project\test\test_mem_leak\test_mem_leak\test_mem_leak.cpp(92) : 6 (92) : {118} normal block at 0x002B9EF8, 5 bytes long. Data: < > CD CD CD CD CD e:\project\test\test_mem_leak\test_mem_leak\test_mem_leak.cpp(92) : 5 (92) : {117} normal block at 0x002B9EB8, 4 bytes long. Data: < > CD CD CD CD e:\project\test\test_mem_leak\test_mem_leak\test_mem_leak.cpp(92) : 4 (92) : {116} normal block at 0x002B9E78, 3 bytes long. Data: < > CD CD CD e:\project\test\test_mem_leak\test_mem_leak\test_mem_leak.cpp(92) : 3 (92) : {115} normal block at 0x002B9E38, 2 bytes long. Data: < > CD CD e:\project\test\test_mem_leak\test_mem_leak\test_mem_leak.cpp(92) : 2 (92) : {114} normal block at 0x002B9DF8, 1 bytes long. Data: < > CD e:\project\test\test_mem_leak\test_mem_leak\test_mem_leak.cpp(92) : 1 (92) : {113} normal block at 0x002B9DB8, 0 bytes long. Data:<>h鴌e:projecttesttest_mem_leak\test_mem_leak\test_mem_leak.cpp(88) : 0 (88) : {112} normal block at 0x002B9D50, 40 bytes long. Data: <0L+ > 30 4C 2B 00 CD CD CD CD CD CD CD CD CD CD CD CD Object dump complete. プログラム「[8796]test_MEM_LEAK.exe:ネイティブ」は終了し、戻り値は-1073741510(0 xc 000013 a)である.
ヒント:
出力ファイルをUEにコピーして、漏洩行番号が発生した回数を検索し、漏洩の数を算出することができる.
作者:iuhsihsow 2013-1-11 12:31:12原文リンクにて発表
読書:73コメント:0コメントを表示
1.工事をdebugに設定
メモリ漏洩の検出は一般的にdebugモードで行われる
2.メモリリークを確認する必要があるcppヘッダに
#ifdef _DEBUG
#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>
#define new new(_NORMAL_BLOCK, __FILE__, __LINE__)
#endif
3.コードにこんな言葉を挿入する
EnableMemLeakCheck();
inline void EnableMemLeakCheck()
{
_CrtSetDbgFlag(_CrtSetDbgFlag(_CRTDBG_REPORT_FLAG) | _CRTDBG_LEAK_CHECK_DF);
}
4.出力で漏れを見ることができます
例を挙げると、例ではnewExで表す上記マクロ定義のnew
int _tmain(int argc, _TCHAR* argv[])
{
EnableMemLeakCheck();
int num = 10;
byte **p = newEx byte *[num];
for (int i = 0; i < num; i ++)
{
Sleep(1);
*p = newEx byte[i];
}
long *pl = newEx long[100];
while(1)
{
Sleep(100);
}
return 0;
}
出力に表示される内容(debugでプログラムを実行し、フォークでプログラムを閉じます)
memory leaks! Dumping objects -> e:\project\test\test_mem_leak\test_mem_leak\test_mem_leak.cpp(101) : {124} normal block at 0x00295CB8, 400 bytes long. Data: < > CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD e:\project\test\test_mem_leak\test_mem_leak\test_mem_leak.cpp(92) : {122} normal block at 0x00294C30, 9 bytes long. Data: < > CD CD CD CD CD CD CD CD CD e:\project\test\test_mem_leak\test_mem_leak\test_mem_leak.cpp(92) : {121} normal block at 0x00294BE8, 8 bytes long. Data: < > CD CD CD CD CD CD CD CD e:\project\test\test_mem_leak\test_mem_leak\test_mem_leak.cpp(92) : {120} normal block at 0x00299F88, 7 bytes long. Data: < > CD CD CD CD CD CD CD e:\project\test\test_mem_leak\test_mem_leak\test_mem_leak.cpp(92) : {119} normal block at 0x00299F40, 6 bytes long. Data: < > CD CD CD CD CD CD e:\project\test\test_mem_leak\test_mem_leak\test_mem_leak.cpp(92) : {118} normal block at 0x00299EF8, 5 bytes long. Data: < > CD CD CD CD CD e:\project\test\test_mem_leak\test_mem_leak\test_mem_leak.cpp(92) : {117} normal block at 0x00299EB8, 4 bytes long. Data: < > CD CD CD CD e:\project\test\test_mem_leak\test_mem_leak\test_mem_leak.cpp(92) : {116} normal block at 0x00299E78, 3 bytes long. Data: < > CD CD CD e:\project\test\test_mem_leak\test_mem_leak\test_mem_leak.cpp(92) : {115} normal block at 0x00299E38, 2 bytes long. Data: < > CD CD e:\project\test\test_mem_leak\test_mem_leak\test_mem_leak.cpp(92) : {114} normal block at 0x00299DF8, 1 bytes long. Data: < > CD e:\project\test\test_mem_leak\test_mem_leak\test_mem_leak.cpp(92) : {113} normal block at 0x00299DB8, 0 bytes long. Data:<>励p e:projecttesttest_mem_leak\test_mem_leak\test_mem_leak.cpp(88) : {112} normal block at 0x00299D50, 40 bytes long. Data: <0L) > 30 4C 29 00 CD CD CD CD CD CD CD CD CD CD CD CD Object dump complete.
書類名と行番号があり、先に申請してから釈放します.
拡張:
実際には別のnewを使用するdbgnew.cppでは、次の例を示します.
void *__CRTDECL operator new[](
size_t cb,
int nBlockUse,
const char * szFileName,
int nLine
)
_THROW1(_STD bad_alloc)
{
void *res = operator new(cb, nBlockUse, szFileName, nLine );
RTCCALLBACK(_RTC_Allocate_hook, (res, cb, 0));
return res;
}
注意、const char*szFileNameは使用できます_file__カスタムクラスを使用してchar*に再ロードすることもできます(老馬のコード提供に感謝します)
例:
char new_index_recorder_file_name[1024 * 1024][256];
class new_index_recorder{
public:
new_index_recorder(char* file, int line) : file(file), line(line){
}
operator char*(){
static unsigned int index;
sprintf(new_index_recorder_file_name[index], "%s(%d) : %d ", file, line, index++);
return new_index_recorder_file_name[index];
}
private:
char* file;
int line;
};
もちろん、char*ポインタを関数で返すこともできます
int g_count = 0;
class OperNew
{
public:
OperNew()
{
g_count ++;
pC = new char[20];
memset(pC, 0, 10);
sprintf(pC, "No.%d", g_count);
}
char* GetChar()
{
return pC;
}
private:
char * pC ;
};
これでカスタムコンテンツを返すことができます.今回の戻りには構造時のシーケンス番号が付けられており、もちろん時間などを追加することもできます.結果は次のとおりです.
e:\project\test\test_mem_leak\test_mem_leak\test_mem_leak.cpp(95) : 11 (95) : {123} normal block at 0x002B4C78, 400 bytes long. Data: < > CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD e:\project\test\test_mem_leak\test_mem_leak\test_mem_leak.cpp(92) : 10 (92) : {122} normal block at 0x002B4C30, 9 bytes long. Data: < > CD CD CD CD CD CD CD CD CD e:\project\test\test_mem_leak\test_mem_leak\test_mem_leak.cpp(92) : 9 (92) : {121} normal block at 0x002B4BE8, 8 bytes long. Data: < > CD CD CD CD CD CD CD CD e:\project\test\test_mem_leak\test_mem_leak\test_mem_leak.cpp(92) : 8 (92) : {120} normal block at 0x002B9F88, 7 bytes long. Data: < > CD CD CD CD CD CD CD e:\project\test\test_mem_leak\test_mem_leak\test_mem_leak.cpp(92) : 7 (92) : {119} normal block at 0x002B9F40, 6 bytes long. Data: < > CD CD CD CD CD CD e:\project\test\test_mem_leak\test_mem_leak\test_mem_leak.cpp(92) : 6 (92) : {118} normal block at 0x002B9EF8, 5 bytes long. Data: < > CD CD CD CD CD e:\project\test\test_mem_leak\test_mem_leak\test_mem_leak.cpp(92) : 5 (92) : {117} normal block at 0x002B9EB8, 4 bytes long. Data: < > CD CD CD CD e:\project\test\test_mem_leak\test_mem_leak\test_mem_leak.cpp(92) : 4 (92) : {116} normal block at 0x002B9E78, 3 bytes long. Data: < > CD CD CD e:\project\test\test_mem_leak\test_mem_leak\test_mem_leak.cpp(92) : 3 (92) : {115} normal block at 0x002B9E38, 2 bytes long. Data: < > CD CD e:\project\test\test_mem_leak\test_mem_leak\test_mem_leak.cpp(92) : 2 (92) : {114} normal block at 0x002B9DF8, 1 bytes long. Data: < > CD e:\project\test\test_mem_leak\test_mem_leak\test_mem_leak.cpp(92) : 1 (92) : {113} normal block at 0x002B9DB8, 0 bytes long. Data:<>h鴌e:projecttesttest_mem_leak\test_mem_leak\test_mem_leak.cpp(88) : 0 (88) : {112} normal block at 0x002B9D50, 40 bytes long. Data: <0L+ > 30 4C 2B 00 CD CD CD CD CD CD CD CD CD CD CD CD Object dump complete. プログラム「[8796]test_MEM_LEAK.exe:ネイティブ」は終了し、戻り値は-1073741510(0 xc 000013 a)である.
ヒント:
出力ファイルをUEにコピーして、漏洩行番号が発生した回数を検索し、漏洩の数を算出することができる.
作者:iuhsihsow 2013-1-11 12:31:12原文リンクにて発表
読書:73コメント:0コメントを表示