vs下C++內存泄露檢測

參考文章:

http://msdn.microsoft.com/zh-cn/library/x98tx3cf.aspx

1、在main方法所在的文件里加上如下代碼:

//可以定位到發生內存泄露 所在的文件和具體那一行,用於檢測 malloc 分配的內存
 2 #define _CRTDBG_MAP_ALLOC 
 3 #include <stdlib.h>
 4 #include <crtdbg.h>
 5 
 6 //把分配內存的信息保存下來,可以定位到那一行發生了內存泄露。用於檢測 new 分配的內存
 7 #ifdef _DEBUG
 8 #define new   new(_NORMAL_BLOCK, __FILE__, __LINE__)
 9 #endif
10 
11 //有用
12 inline void EnableMemLeakCheck()
13 {
14     //該語句在程序退出時自動調用 _CrtDumpMemoryLeaks(),用於多個退出出口的情況.
15     //如果只有一個退出位置,可以在程序退出之前調用 _CrtDumpMemoryLeaks()
16    _CrtSetDbgFlag(_CrtSetDbgFlag(_CRTDBG_REPORT_FLAG) | _CRTDBG_LEAK_CHECK_DF);
17 }
複製代碼

 

2、在main方法裏開始的地方調用 EnableMemLeakCheck() 方法。到此爲止,可以檢測的內存泄露的信息裏,有一部分是可以定位到具體的文件以及所在的行的,但還是有一些其他工程或者其他文件裏如果發生內存泄露還是沒有定位到具體的文件和行,這些信息會在vs的輸出窗口裏看到。如下面的輸出,第一處泄露有很具體的定位信息,第二處的泄露卻沒有。

1 q:\project_wydxml\wydxmlcreator\project_win32\wydxmlcreator.cpp(52) : {256} normal block at 0x00ABBC40, 200 bytes long.
2  Data: <                > CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD 
3 {254} normal block at 0x00ABF6F8, 10 bytes long.
4  Data: <          > CD CD CD CD CD CD CD CD CD CD 

 

3、對於那些沒有定位出具體位置的內存泄露處理如下:記錄下該處內存是第幾次分配的,比如上面的第三行和第四行表示第二處內存泄露,第三行裏 {}裏的254表示該處泄露的內存是第 254 次分配的。結束運行,在 EnableMemLeakCheck() 方法 後加上一句代碼: _CrtSetBreakAlloc(254); 括號裏的參數就是沒有得到準確定位的泄露內存的被分配的序數,其他的就別改了,再次運行,程序就會在 分配 第 254 塊 內存時進入斷點,通過斷點堆棧就可以比較方便的知道哪些泄露了。

 

4、注意事項:對於 new 出來的一些自定義類的對象,直接調用其析構方法時,EnableMemLeakCheck 還是會將其視作沒有釋放內存的,要直接調用 delete xxx 才行。。。如: A *a = new A();  a->~A(); 會被判做有問題的, delete a 才視作沒問題。。。。

 

5、令外,還有個監控某片代碼段是否有內存泄露的,如下。如果有這段代碼有泄露,_CrtMemDifference就會比較出來,然後 _CrtMemDumpStatistics輸出相關信息。輸出的信息沒有具體的定位到具體文件具體哪一行,但有時還是有些輔助作用的吧

複製代碼
1 _CrtMemState s1, s2, s3;
2 _CrtMemCheckpoint( &s1 );
3 
4 //your code
5 
6 CrtMemCheckpoint( &s2 );
7 if ( _CrtMemDifference( &s3, &s1, &s2) )
8      _CrtMemDumpStatistics( &s3 );
複製代碼

 

 

 

全部代碼如下:

複製代碼
 1 #include "stdafx.h"
 2 #include <iostream>
 3 #include "wydxml.h"
 4 
 5 //可以定位到發生內存泄露 所在的文件和具體那一行,用於檢測 malloc 分配的內存
 6 #define _CRTDBG_MAP_ALLOC 
 7 #include <stdlib.h>
 8 #include <crtdbg.h>
 9 
10 //把分配內存的信息保存下來,可以定位到那一行發生了內存泄露。用於檢測 new 分配的內存
11 #ifdef _DEBUG
12 #define new   new(_NORMAL_BLOCK, __FILE__, __LINE__)
13 #endif
14 
15 //有用
16 inline void EnableMemLeakCheck()
17 {
18     //該語句在程序退出時自動調用 _CrtDumpMemoryLeaks(),用於多個退出出口的情況.
19     //如果只有一個退出位置,可以在程序退出之前調用 _CrtDumpMemoryLeaks()
20    _CrtSetDbgFlag(_CrtSetDbgFlag(_CRTDBG_REPORT_FLAG) | _CRTDBG_LEAK_CHECK_DF);
21 }
22 
23 
24 int _tmain(int argc, _TCHAR* argv[])
25 {
26     
27     EnableMemLeakCheck();
28 
29     //運行到 第 191 次 內存分配的時候停下來
30     //_CrtSetBreakAlloc(191);
31 
32     char* p = new char[100];
33     char* p1 = new char[200];
34     char* p2 = (char*)malloc(600);
35     delete p;
36 
37     getchar();
38 
39     //_CrtDumpMemoryLeaks();//這個代碼好像會輸出額外多餘的內存分配信息
40     return 0;
41 }

發佈了45 篇原創文章 · 獲贊 12 · 訪問量 7萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章