VC++ 內存泄露與檢測的一種方法

    本文介紹,當VC++或者MFC程序,出現內存泄露時,如何快速定位的方法,這種方法有必定的侷限性,在注意事項中會給出的。多線程

MFC程序

    當MFC程序出現內存泄露時,退出程序時的VS調試輸出窗口,通常會有以下顯示:函數

image

   上面顯示了在程序的哪一個文件的哪行語句,發生了內存泄露,其中:工具

   {345}: 表示 內存分配編號.net

   normal block:表示 內存塊類型,有普通塊(普通程序分配)、客戶端塊(分配基於CObject的內存)和CRT塊(庫函數內部分配)這幾種類型線程

   0x0074A030:以16進制形式輸出的內存位置調試

   40 bytes long: 以字節爲單位的內存塊大小orm

   Data<   >CD CD ..:內存塊前16個字節的內容,16進製表示。blog

      定位內存泄露位置,能夠雙擊泄露信息,也能夠在輸出窗口 按F4鍵,跳轉到 出錯行。內存

 

普通VC++程序

    在普通VC++程序中,要相似MFC中內存檢測的效果,須要作以下操做。get

    1.  在頭文件中,添加  #include <ctrdbg.h>

    2.  在程序入口最開始處,添加 下面兩句話便可

        _CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );    //設置調試堆函數跟蹤分配的方式
        //_CrtSetBreakAlloc();     //這句話,在確實有內存泄露的狀況下,給 內存分配編號

    3. 按F5,運行程序,等待程序退出後,在輸出窗口能夠看到下面的狀況:

      image

     如圖所示,程序有兩處內存泄露地方,分配編號爲 476 和 475,此時,給_CrtSetBreakAlloc()函數傳入476參數,再次運行程序,在退出時,會彈出以下窗口:

     image

點擊 中斷  跳到,_CrtSetBreakAlloc()中斷的地方,而後在程序中,經過查看調用堆棧,就能夠看到應用程序的哪一次new操做沒有執行delete操做。

在中斷的同時,也能夠從控制檯中,看到整個程序析構的順序,以下圖所示:

image

 

注意事項

1. 當程序確認沒有內存泄露時,不能夠調用_CrtSetBreakAlloc(475),由於,這樣會在指定內存分配次數發生時,強制中斷程序。

2. 這種檢測內存分配的方式,要求,程序在執行過程當中,是可還原的(屢次執行過程的內存分配順序不會發送變化),這個假設,在多數狀況下是成立的,不過,在多線程執行的環境下,有時候難以保證。

3. 對於普通C程序,上述檢測方法也是成立的,只不過new換成了malloc,delete換成了free

4. 好比 int *p = new int[4]; delete p; 這種方式的泄露,上述方法是檢測不出來,此時,須要cppcheck等更有力的工具來檢查。

 

參考連接:C++調試堆

相關文章
相關標籤/搜索