本文介紹,當VC++或者MFC程序,出現內存泄露時,如何快速定位的方法,這種方法有必定的侷限性,在注意事項中會給出的。多線程
MFC程序
當MFC程序出現內存泄露時,退出程序時的VS調試輸出窗口,通常會有以下顯示:函數
上面顯示了在程序的哪一個文件的哪行語句,發生了內存泄露,其中:工具
{345}: 表示 內存分配編號.net
normal block:表示 內存塊類型,有普通塊(普通程序分配)、客戶端塊(分配基於CObject的內存)和CRT塊(庫函數內部分配)這幾種類型線程
0x0074A030:以16進制形式輸出的內存位置調試
40 bytes long: 以字節爲單位的內存塊大小orm
Data< >CD CD ..:內存塊前16個字節的內容,16進製表示。blog
定位內存泄露位置,能夠雙擊泄露信息,也能夠在輸出窗口 按F4鍵,跳轉到 出錯行。內存
在普通VC++程序中,要相似MFC中內存檢測的效果,須要作以下操做。get
1. 在頭文件中,添加 #include <ctrdbg.h>
2. 在程序入口最開始處,添加 下面兩句話便可
_CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF ); //設置調試堆函數跟蹤分配的方式
//_CrtSetBreakAlloc(); //這句話,在確實有內存泄露的狀況下,給 內存分配編號
3. 按F5,運行程序,等待程序退出後,在輸出窗口能夠看到下面的狀況:
如圖所示,程序有兩處內存泄露地方,分配編號爲 476 和 475,此時,給_CrtSetBreakAlloc()函數傳入476參數,再次運行程序,在退出時,會彈出以下窗口:
點擊 中斷 跳到,_CrtSetBreakAlloc()中斷的地方,而後在程序中,經過查看調用堆棧,就能夠看到應用程序的哪一次new操做沒有執行delete操做。
在中斷的同時,也能夠從控制檯中,看到整個程序析構的順序,以下圖所示:
1. 當程序確認沒有內存泄露時,不能夠調用_CrtSetBreakAlloc(475),由於,這樣會在指定內存分配次數發生時,強制中斷程序。
2. 這種檢測內存分配的方式,要求,程序在執行過程當中,是可還原的(屢次執行過程的內存分配順序不會發送變化),這個假設,在多數狀況下是成立的,不過,在多線程執行的環境下,有時候難以保證。
3. 對於普通C程序,上述檢測方法也是成立的,只不過new換成了malloc,delete換成了free
4. 好比 int *p = new int[4]; delete p; 這種方式的泄露,上述方法是檢測不出來,此時,須要cppcheck等更有力的工具來檢查。
參考連接:C++調試堆