內存泄露檢測方法[嘗試+未解的開放問題]



內存泄露檢測方法[嘗試+未解的開放問題]

 

 

 

        MFC程序,能夠檢測到內存泄漏,且寫在debug窗口下顯示具體的泄露位置,雙擊即可到泄露的地方,比較方便。

win32控制檯應用程序,則需要進行一些設置:


0.準備工作:用啥檢測內存? 

    1. CRT

      1. 在需要main函數所在cpp中加入下面代碼:

         

#define_CRTDBG_MAP_ALLOC

#include<stdlib.h>

#include<crtdbg.h>

 

    1. vld工具:

      1. 網上有一堆VLD工具的介紹,我現在用的是vc6.0+vld;

      2. 配置好vld,之後再在工程加#include <vld.h> 就可以自動測了;

         

  1. 若使用CRT檢測,可以這樣:

     

設置報告模式

      _CrtSetDbgFlag(_CrtSetDbgFlag(_CRTDBG_REPORT_FLAG) | _CRTDBG_LEAK_CHECK_DF);

在適當的位置檢測------個適[Jsy1] 當的位置,其實我還沒找到。。。。[Jsy2] 

      _CrtDumpMemoryLeaks();

如何把報告輸出成文件:(可以不做這一步)

HANDLEhLogFile;//聲明日誌文件句柄  

char dumpPath[255];

sprintf(dumpPath,"%s","E:\\log\\memlog.log");

hLogFile =CreateFile(dumpPath,GENERIC_WRITE,FILE_SHARE_WRITE|FILE_SHARE_READ,

NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);//創建日誌文件

_CrtSetReportMode(_CRT_WARN,_CRTDBG_MODE_FILE|_CRTDBG_MODE_DEBUG);//warn級別的內容都輸出到文件(注意dump  報告級別即爲warning

 _CrtSetReportFile(_CRT_WARN,hLogFile);//將日誌文件設置爲告警的輸出文件

 

奇怪的是:我的控制檯程序中,Main中明明什麼都沒幹,卻出現了這樣的泄露問題:

c:\program files (x86)\microsoft visualstudio\vc98\include\crtdbg.h(552) : {59} normal block at 0x01DE1760, 33 byteslong.

 Data: < C             > 00 43 00 CD CD CD CD CD CDCD CD CD CD CD CD CD

c:\program files (x86)\microsoft visualstudio\vc98\include\crtdbg.h(552) : {58} normal block at 0x01DE17B0, 40 byteslong.

 Data: <HJD            > 48 4A 44 00 16 00 00 00 00 0000 00 00 00 00 00

Object dump complete.

這樣即使定位到了crtdbg.h也看不出來是啥原因導致的

 

不甘心,又改用vld檢測到下面信息(這個問題不知道是怎麼出來的。。。。。)

WARNING:Visual Leak Detector detected memory leaks!

----------Block 1 at 0x02860598: 42338000 bytes ----------

 Call Stack:

   sbheap.c (102):Fill_FID.exe!__sbh_heap_init + 0x13 bytes

   heapinit.c (59): Fill_FID.exe!_heap_init +0x5 bytes

   crt0.c (139): Fill_FID.exe!mainCRTStartup +0x7 bytes

   0x7710338A (File and line number notavailable): kernel32.dll!BaseThreadInitThunk + 0x12 bytes

   0x77A99F72 (File and line number notavailable): ntdll.dll!RtlInitializeExceptionChain + 0x63 bytes

   0x77A99F45 (File and line number notavailable): ntdll.dll!RtlInitializeExceptionChain + 0x36 bytes

 Data:

   0D F0 AD BA    0D F0AD BA   0D F0 AD BA    0D F0 AD BA     ........ ........

   0D F0 AD BA    0D F0 AD BA    0D F0 AD BA    0D F0 AD BA     ........ ........

   0D F0 AD BA    0D F0 AD BA    0D F0 AD BA    0D F0 AD BA     ........ ........

   0D F0 AD BA    0D F0 AD BA    0D F0 AD BA    0D F0 AD BA     ........ ........

   0D F0 AD BA    0D F0 AD BA    0D F0 AD BA    0D F0 AD BA     ........ ........

   0D F0 AD BA    0D F0 AD BA    0D F0 AD BA    0D F0 AD BA     ........ ........

   0D F0 AD BA    0D F0 AD BA   0D F0 AD BA   0D F0 AD BA     ........ ........

   0D F0 AD BA    0D F0 AD BA    0D F0 AD BA    0D F0 AD BA     ........ ........

   0D F0 AD BA    0D F0 AD BA    0D F0 AD BA    0D F0 AD BA     ........ ........

   0D F0 AD BA    0D F0 AD BA    0D F0 AD BA    0D F0 AD BA     ........ ........

   0D F0 AD BA    0D F0 AD BA    0D F0 AD BA    0D F0 AD BA     ........ ........

   0D F0 AD BA    0D F0 AD BA    0D F0 AD BA    0D F0 AD BA     ........ ........

   0D F0 AD BA    0D F0 AD BA    0D F0 AD BA    0D F0 AD BA     ........ ........

   0D F0 AD BA    0D F0 AD BA    0D F0 AD BA    0D F0 AD BA     ........ ........

   0D F0 AD BA    0D F0 AD BA    0D F0 AD BA    0D F0 AD BA     ........ ........

   0D F0 AD BA    0D F0 AD BA    0D F0 AD BA    0D F0 AD BA     ........ ........

 

 

VisualLeak Detector detected 1 memory leak (20644 bytes).

Largestnumber used: 22612 bytes.

Totalallocations: 24708 bytes.

VisualLeak Detector is now exiting.

Thethread 0x3158 has exited with code 0 (0x0).

  1. 臨時策略:

    1. 1中用到的crt,看到有些介紹,說的是,程序運行到1.(b)語句爲止沒有被釋放的內存就會被檢測到。又由於main函數並不是程序真正意義上的第一個運行的,前面還要經歷heap_init一類的分配、初始化工作(具體流程不是很清楚),因此可能將   _CrtDumpMemoryLeaks();語句放在main函數return之前感覺並不妥當。

    2. 剛好看到有關內存狀態快照的篇文章,原理就是在main開始的時候取一次內存狀態快照,在main即將結束得時候再取一次快照,比較差異就能知道main函數中有沒有泄露了。具體如下:

    3.  

      1. main開始的地方加入下列代碼:

 

_CrtMemState s1, s2, s3;//定義3個臨時內存狀態  

_CrtMemCheckpoint( &s1 );//獲取第一個內存狀態快照

 

      1. main函數return之前,加入

           

//以下部分非必要,僅爲方便後續分析增加信息

           _CrtMemCheckpoint( &s2 );

           if (_CrtMemDifference( &s3,&s1, &s2) )

           {

                      _CrtMemDumpStatistics(&s3 );//dump相鄰時間點間的內存塊變化

                      //for next compare

                      _CrtMemCheckpoint( &s1);

           }

 

 

 

總結:使用了臨時策略,就不再報那個莫名其妙的泄露問題了,但總感覺有些隱患被我埋下了,要是有清楚這個的,幫忙看一下。

                         

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章