使用Visual Leak Detector for Visual C++ 捕捉內存泄露


 

什么是內存泄漏?

       內存泄漏(memory leak),指由於疏忽或錯誤造成程序未能釋放已經不再使用的內存的情況。內存泄漏並非指內存在物理上的消失,而是應用程序分配某段內存后,由於設計錯誤,失去了對該段內存的控制,因而造成了內存的浪費。

 

CC++內存泄露

       對於C和C++這種沒有Garbage Collection 的語言來講,我們主要關注兩種類型的內存泄漏:

       堆內存泄漏(Heap leak)。對內存指的是程序運行中根據需要通過malloc,realloc, new等從堆中分配的一塊內存,完成后必須通過調用對應的 free或者delete 釋放掉。如果程序設計的錯誤導致這部分內存沒有被釋放,那么此后這塊內存將不會被使用,就會產生Heap Leak.

       系統資源泄露(Resource Leak)。主要指程序使用系統分配的資源比如 Bitmap,Handle,SOCKET等沒有使用相應的函數釋放掉,導致系統資源的浪費,嚴重可導致系統效能降低,系統運行不穩定。

 

如何解決內存泄露?

        內存泄露的問題其困難在於:

       1、編譯器不能發現這些問題。

       2、運行時才能捕獲到這些錯誤,這些錯誤沒有明顯的症狀,時隱時現。

       3、對於手機等終端開發用戶來說,尤為困難。

       下面從三個方面來解決內存泄露:

       第一,良好的編碼習慣,盡量在涉及內存的程序段,檢測出內存泄露。當程序穩定之后,再來檢測內存泄露時,無疑增加了排除的難度和復雜度。

       使用了內存分配的函數,要記得要使用其釋放函數釋放掉。

       Heap memory

       malloc\realloc ------  free

       new \new[] ----------  delete \delete[]

       GlobalAlloc------------GlobalFree

 

       Resource Leak :

       對於系統資源使用之前要仔細看其使用說明,防止錯誤使用或者忘記釋放掉系統資源。

 

       對於基於引用計數的系統對象尤其要注意,因為只有其引用計數為0時,該對象才能正確被刪除。而其使用過程中又生成的新的系統資源,使用完畢后,如果沒有及時刪除,都會影響其引用計數。

 

使用Visual Leak Detector for Visual C++

       簡介

       Visual Leak Detector是一款免費的、健全的、開源的Visual C++內存泄露檢測系統。相比Visual C++自帶的內存檢測機制,Visual Leak Detector可以顯示導致內存泄露的完整內存分配調用堆棧。

       使用方法

       VLD簡單易用,文檔也很豐富,對於內存泄露的具體位置也能以調用堆棧的形式詳細的顯示出來。

       下載安裝后,僅僅需要告訴Visual C++在哪里找到include文件和lib文件。

         C/C++ -> General -> Additional Include Directories = C:\Program Files (x86)\Visual Leak Detector\include

         Linker -> General -> Additional Library Directories = C:\Program Files (x86)\Visual Leak Detector\lib\Win32

         Linker -> Input-> Additional Dependencies = vld.lib

       然后,在代碼上的變動就只需要簡單的加上#include <vld.h> 就可以了。

       當你在Visual C++中調試運行你的程序時,在程序結束后VLD將在output窗口輸出一個內存泄露報告,該報告包括了你的程序中內存分配的完成調用棧信息。雙擊調用棧的某一行,就可以迅速跳轉到你的代碼編輯器相應的位置。

       Visual Leak Detector有一些配置項,可以設置內存泄露報告的保存地(文件、調試器),拷貝"\Visual Leak Detector"路徑下的vld.ini文件到工程的Debug目錄下(在IDE運行的話,則需要拷貝到工程目錄下),修改以下項:

       ReportFile = .\memory_leak_report.txt

       ReportTo = both

       可以看到在Debug目錄下生成文件memory_leak_report.txt,跟VS中Output窗口輸出的內容一樣。

       總之,VLD是一種高效的診斷、修復C/C++程序內存泄露的方法。

      

       應用舉例

 #include "stdafx.h"
 #ifdef _DEBUG    //在Release模式下,不會鏈接Visual Leak Detector
 #include "vld.h"
 #endif
  int _tmain(int argc, _TCHAR* argv[])
  {
        char* ch1 = new char[100];
        char* ch2 = (char*)malloc(200);

         /*
        if (ch1 != NULL)
        {
              delete[] ch1;
              ch1 = NULL;
        }
        if (ch2 != NULL)
        {
              free(ch2);
              ch1 = NULL;
        }
         */

        return 0;
   }

Output輸出

Visual Leak Detector Version 2.2.3 installed.

WARNING: Visual Leak Detector detected memory leaks!

---------- Block 1 at 0x008CD6F8: 100 bytes ----------

  Call Stack:

    c:\users \consoleapplication\consoleapplication.cpp (12): ConsoleApplication.exe!wmain + 0x7 bytes

    f:\dd\vctools\crt_bld\self_x86\crt\src\crtexe.c (533): ConsoleApplication.exe!__tmainCRTStartup + 0x19 bytes

    f:\dd\vctools\crt_bld\self_x86\crt\src\crtexe.c (377): ConsoleApplication.exe!wmainCRTStartup

    0x74EE8543 (File and line number not available): KERNEL32.DLL!BaseThreadInitThunk + 0xE bytes

    0x770EAC69 (File and line number not available): ntdll.dll!RtlInitializeExceptionChain + 0x85 bytes

    0x770EAC3C (File and line number not available): ntdll.dll!RtlInitializeExceptionChain + 0x58 bytes

  Data:

    CD CD CD CD    CD CD CD CD    CD CD CD CD    CD CD CD CD     ........ ........

    CD CD CD CD    CD CD CD CD    CD CD CD CD    CD CD CD CD     ........ ........

    CD CD CD CD    CD CD CD CD    CD CD CD CD    CD CD CD CD     ........ ........

    CD CD CD CD    CD CD CD CD    CD CD CD CD    CD CD CD CD     ........ ........

    CD CD CD CD    CD CD CD CD    CD CD CD CD    CD CD CD CD     ........ ........

    CD CD CD CD    CD CD CD CD    CD CD CD CD    CD CD CD CD     ........ ........

    CD CD CD CD                                                  ........ ........

 

 

---------- Block 2 at 0x008CD798: 200 bytes ----------

  Call Stack:

    c:\users\ \consoleapplication\consoleapplication.cpp (13): ConsoleApplication.exe!wmain + 0xD bytes

    f:\dd\vctools\crt_bld\self_x86\crt\src\crtexe.c (533): ConsoleApplication.exe!__tmainCRTStartup + 0x19 bytes

    f:\dd\vctools\crt_bld\self_x86\crt\src\crtexe.c (377): ConsoleApplication.exe!wmainCRTStartup

    0x74EE8543 (File and line number not available): KERNEL32.DLL!BaseThreadInitThunk + 0xE bytes

    0x770EAC69 (File and line number not available): ntdll.dll!RtlInitializeExceptionChain + 0x85 bytes

    0x770EAC3C (File and line number not available): ntdll.dll!RtlInitializeExceptionChain + 0x58 bytes

  Data:

    CD CD CD CD    CD CD CD CD    CD CD CD CD    CD CD CD CD     ........ ........

    CD CD CD CD    CD CD CD CD    CD CD CD CD    CD CD CD CD     ........ ........

    CD CD CD CD    CD CD CD CD    CD CD CD CD    CD CD CD CD     ........ ........

    CD CD CD CD    CD CD CD CD    CD CD CD CD    CD CD CD CD     ........ ........

    CD CD CD CD    CD CD CD CD    CD CD CD CD    CD CD CD CD     ........ ........

    CD CD CD CD    CD CD CD CD    CD CD CD CD    CD CD CD CD     ........ ........

    CD CD CD CD    CD CD CD CD    CD CD CD CD    CD CD CD CD     ........ ........

    CD CD CD CD    CD CD CD CD    CD CD CD CD    CD CD CD CD     ........ ........

    CD CD CD CD    CD CD CD CD    CD CD CD CD    CD CD CD CD     ........ ........

    CD CD CD CD    CD CD CD CD    CD CD CD CD    CD CD CD CD     ........ ........

    CD CD CD CD    CD CD CD CD    CD CD CD CD    CD CD CD CD     ........ ........

    CD CD CD CD    CD CD CD CD    CD CD CD CD    CD CD CD CD     ........ ........

    CD CD CD CD    CD CD CD CD                                   ........ ........

 

Visual Leak Detector detected 2 memory leaks (372 bytes).

Largest number used: 372 bytes.

Total allocations: 372 bytes.

Visual Leak Detector is now exiting.

The program '[0x262C] ConsoleApplication1.exe' has exited with code 0 (0x0).

 

輸出的部分主要分為兩塊

       Call Stack部分:

       是泄露內存的調用堆棧,其中顯示了泄露資源創建的位置,雙擊便可以定位到相應的代碼部分。

       Data部分:

       即泄露部分的內存內容。


免責聲明!

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



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