#include
// 程式結束前呼叫
_CrtDumpMemoryLeaks();
自動化:在程式進入點 (main/WinMain) 最開頭加入:
_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
CRT 將在每個 `exit` 路徑自動呼叫 `_CrtDumpMemoryLeaks`。
適用於「某區塊代碼前後」的洩漏偵測:
_CrtMemState s1, s2, s3;
_CrtMemCheckpoint(&s1); // 記錄初始狀態
// --- 待測試代碼區塊 ---
int* p = new int[100];
delete[] p; // 故意漏掉 delete 會被偵測
// ----------------------
_CrtMemCheckpoint(&s2); // 記錄結束狀態
if (_CrtMemDifference(&s3, &s1, &s2)) { // 比較差異存入 s3
_CrtMemDumpAllObjectsSince(&s3); // 輸出 s3 以來所有未釋放物件
}
預設輸出至 Debug Output 視窗,可導向檔案或訊息盒:
// 需 ATL 或手動 CreateFile
CAtlFile file;
file.Create(_T("D:\\leak_report.txt"), GENERIC_WRITE, FILE_SHARE_WRITE, CREATE_ALWAYS);
_CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE);
_CrtSetReportFile(_CRT_WARN, file.m_h); // ATL CAtlFile 隱含轉換
// 或純 Win32
HANDLE hFile = CreateFile(_T("D:\\leak_report.txt"), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
_CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE);
_CrtSetReportFile(_CRT_WARN, hFile);
_CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_WNDW); // 彈出 終止/重試/忽略 視窗
int MyReportHook(int reportType, char* msg, int* retval) {
*retval = 0;
if (reportType == _CRT_WARN) {
// 自訂處理:寫 Log、發送網路、GUI 顯示等
OutputDebugStringA("[LEAK] ");
OutputDebugStringA(msg);
OutputDebugStringA("\n");
}
return TRUE; // TRUE=不再傳遞給預設處理器
}
// 安裝
_CrtSetReportHook(MyReportHook);
CMemoryState ms1, ms2, ms3;
ms1.Checkpoint();
// ... 測試代碼 ...
ms2.Checkpoint();
if (ms3.Difference(ms1, ms2))
ms3.DumpAllObjectsSince(); // 輸出至 afxDump (Debug Output)
Detected memory leaks!
D:\Project\Test.cpp(15) : {123} normal block at 0x004A3B20, 40 bytes long.
Data: < > CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD
```
- `{123}`:配置序號,可用 `_CrtSetBreakAlloc(123)` 中斷
- `normal block`:一般 `new/malloc` 配置
- `client block`:MFC `DEBUG_NEW` 配置 (含檔案/行號)
- `Data`:前 16 位元組內容 (十六進位),`CD` 為 Debug 填充模式
七、整合到專案的標準啟動碼
// stdafx.cpp 或 main.cpp 最開頭
#ifdef _DEBUG
#include
// 自動報告 + 檔案輸出
_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
// 可選:_CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE); _CrtSetReportFile(_CRT_WARN, hLogFile);
#endif