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


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

MFC程序

    當MFC程序出現內存泄露時,退出程序時的VS調試輸出窗口,一般會有如下顯示:

image

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

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

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

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

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

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

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

 

普通VC++程序

    在普通VC++程序中,要類似MFC中內存檢測的效果,需要做如下操作。

    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++調試堆


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM