1、首先需要宏定義一下new運算符
#ifdef _DEBUG #define new new(_NORMAL_BLOCK,__FILE__,__LINE__)
#endif // DEBUG
解釋:
new(a, b, c) T;
會被解釋成一個函數調用operator new(sizeof(T), a, b, c)。這是C++就有的行為 operator new, operator new[],user-defined placement allocation functions。這里就是把那幾個參數傳給重載的operator new,這樣可以在operator new里面記錄下來 _NORMAL_BLOCK, __FILE__, __LINE__,調試的時候就能看到是在哪里new的。
_NORMAL_BLOCK
mingw-w64 的 crtdbg.h 里這個宏展開成整數 1 。意味着分配 1 個對象的內存。
__FILE__
文件名
__LINE__
第幾行
2、控制調試堆管理器 (僅限調試版本) 的分配行為
//程序開始就調用一下這個函數
void EnableMemLeakCheck() { int tmpFlag = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG); tmpFlag |= _CRTDBG_LEAK_CHECK_DF; _CrtSetDbgFlag(tmpFlag); }
//函數原型 int _CrtSetDbgFlag( int newFlag);
參數
newFlag
新狀態的_crtDbgFlag。
返回值
返回的前一狀態_crtDbgFlag。
備注
_CrtSetDbgFlag函數允許應用程序來控制調試堆管理器通過修改的位域跟蹤內存分配的方式_crtDbgFlag標志。 通過設置位(打開),該應用程序可指示調試堆管理器執行特殊的調試操作,包括在應用程序退出時檢查內存泄露並報告是否找到任何內存泄露、通過指定已釋放的內存塊應保留在堆的鏈接列表中來模擬內存不足情況,以及通過在每次分配請求時檢查每個內存塊來驗證該堆的完整性。 當 _DEBUG未定義,則調用_CrtSetDbgFlag在預處理過程中刪除。
因為設置位將導致診斷輸出增加、程序執行速度減慢,因此在默認情況下不會設置這些位(已關閉)。
介紹一下函數中用到的一些值
_CRTDBG_REPORT_FLAG
調用_CrtSetDbgFlag與newFlag等於_CRTDBG_REPORT_FLAG以獲取當前_crtDbgFlag狀態,並在臨時變量中存儲返回的值。
_CRTDBG_LEAK_CHECK_DF
執行自動泄露檢查在程序退出時通過調用 _CrtDumpMemoryLeaks ,則生成錯誤報告,如果應用程序未能釋放其所分配的所有內存。
示例:
#include <string.h> #include <stdio.h> #include <string> #include <algorithm> #include <vector> #include <iostream> #ifdef _DEBUG #define new new(_NORMAL_BLOCK,__FILE__,__LINE__)
#endif // DEBUG
using namespace std; const int maxn = 1e5 + 5; const int INF = 0x3f3f3f3f; typedef long long ll; void EnableMemLeakCheck() { int tmpFlag = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG); tmpFlag |= _CRTDBG_LEAK_CHECK_DF; _CrtSetDbgFlag(tmpFlag); } class people{ public : int *a; people() :a(new int(5)) { } }; void test() { people *p = new people; delete p->a; //delete p; //故意不delete,程序控制台會打印出內存泄漏的位置
} int main() { EnableMemLeakCheck(); test(); system("pause"); return 0; } /* 輸出: Detected memory leaks! Dumping objects -> f:\vs_workspace\practice\practice\practice.cpp(58) : {146} normal block at 0x000002880770FBF0, 8 bytes long. Data: <PRp > 50 52 70 07 88 02 00 00 Object dump complete. */
#ifdef _DEBUG#define new new(_NORMAL_BLOCK,__FILE__,__LINE__)#endif // DEBUG