1. 程式人生 > >c/c++使用 CRT 庫查找內存泄漏

c/c++使用 CRT 庫查找內存泄漏

stdlib.h def pri epo clu mod 未定義 byte sizeof

前言:

內存泄漏,即未能正確釋放以前分配的內存,是 C/C++ 應用程序中最難以捉摸也最難以檢測到的 Bug 之一。 最初少量內存泄漏可能不引人註目,但隨著時間的推移,內存泄漏越來越多,就會出現一些征兆,包括性能下降,在應用程序內存不足時發生崩潰。 更嚴重的是,占用了所有可用內存的泄漏應用程序可能會導致其他應用程序崩潰,從而無法確定問題出在哪個應用程序。 即使看似無害的內存泄漏也可能說明存在其他問題應當糾正。

借助 Visual Studio 調試器和 C 運行時 (CRT) 庫,可以檢測和識別內存泄漏。

啟動內存泄漏檢測:

檢測內存泄漏的主要工具是調試器和 C 運行庫 (CRT) 調試堆函數。

若要啟用調試堆函數,請在程序開頭包括以下語句:

#define _CRTDBG_MAP_ALLOC
 #include <stdlib.h> 
#include <crtdbg.h>  

且引用順序不能改變!!

使用這些語句啟用調試堆函數之後,可以在某個應用程序退出點之前設置一個對 _CrtDumpMemoryLeaks 的調用,以便在應用程序退出時顯示內存泄漏報告:

_CrtDumpMemoryLeaks();

如果應用程序有多個退出點,並不需要在每個退出點都手動設置一個對 _CrtDumpMemoryLeaks 的調用。 main函數開頭部分對 _CrtSetDbgFlag

的調用會導致在每個退出點自動調用 _CrtDumpMemoryLeaks。 你必須設置兩個位域,如下所示:

_CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF ); 

默認情況下,_CrtDumpMemoryLeaks 將內存泄漏報告輸出到“輸出”窗口的“調試”窗格中。 你可以使用 _CrtSetReportMode 將該報告重定向到其他位置。

如果使用庫,該庫可能會將輸出重置到另一位置。 在此情況下,可以將輸出位置設置回“輸出”窗口,如下所示:

_CrtSetReportMode( _CRT_ERROR, _CRTDBG_MODE_DEBUG ); 

實例:

 1 #define _CRTDBG_MAP_ALLOC
 2 #include <stdlib.h>
 3 #include <crtdbg.h>           //為了 CRT 函數能夠正常工作,#include 語句必須遵循此處所示的順序
 4 #include <stdio.h>  
 5 
 6 int main() {
 7     _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
 8     char*a = NULL;//聲明一個char*類型的指針
 9 
10     a = (char*)malloc( sizeof(char)*100);  //使用malloc分配內存的首地址,然後賦值給a
11 
12     if (!a)
13 
14     {
15         perror("malloc");
16         return-1;
17     }
18 
19     sprintf(a, "%s", "Hello  World\n");  //"HelloWorld\n"寫入a指向的地址
20 
21     printf("%s\n", a);  //輸出用戶輸入的數據
22 
23     //free(a);  //釋放掉使用的內存地址
24     system("pause");
25     return 0;
26 }
27     

為了測試,我們將free(a)註釋掉,得到的結果如下:

Detected memory leaks!
Dumping objects ->
d:\c++lianxi\c++items\neicun\neicun\test.cpp(10) : {81} normal block at 0x002DC1E0, 100 bytes long.
 Data: <Hello  World    > 48 65 6C 6C 6F 20 20 57 6F 72 6C 64 0A 00 CD CD 
Object dump complete.
  • 內存分配編號,在本例中為 81

  • 塊類型,在本例中為 normal

  • 十六進制內存位置,在本例中為0x002DC1E0。

  • 塊的大小,在本例中為 100 bytes

  • 塊中前 16 個字節的數據(十六進制形式)

如果應用程序未定義 _CRTDBG_MAP_ALLOC,則 _CrtDumpMemoryLeaks 顯示的內存泄漏報告如下所示:

Detected memory leaks! Dumping objects -> {18} normal block at 0x00780E80, 64 bytes long. Data: <                > CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD Object dump complete. 

區別在於,第一份報告顯示文件名,以及泄漏的內存初次分配所在位置的行號。

不論是否定義 _CRTDBG_MAP_ALLOC,內存泄漏報告都顯示上面的信息。

c/c++使用 CRT 庫查找內存泄漏