程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> VisualStudio 怎麼使用Visual Leak Detector,visualstudioleak

VisualStudio 怎麼使用Visual Leak Detector,visualstudioleak

編輯:C++入門知識

VisualStudio 怎麼使用Visual Leak Detector,visualstudioleak


那麼在Windows下有什麼好的內存洩漏檢測工具呢?微軟提供Visual Studio開發工具本身沒有什麼太好的內存洩漏檢測功能,我們可以使用第三方工具Visual Leak Detector(以下簡稱vld)。

vld工具是VC++環境下一款小巧易用、免費開源的內存洩漏檢測工具,vld可以顯示導致內存洩漏的完整內存分配調用堆棧。vld的檢測報告能夠對每個內存洩漏點提供完整的堆棧跟蹤,並且包含其源文件及行號信息。

安裝過程是,先在到地址http://vld.codeplex.com/下載vld安裝文件,然後進行安裝,安裝過程中需要安裝程序會配置環境變量。我們需要記住安裝目錄。

安裝完成後打開要檢測的Visual Studio工程,我們需要在工程中配置:vld頭文件目錄和vld庫目錄。

選中游戲工程,打開菜單“項目”→ “屬性”彈出工程屬性對話框,如圖所示,選擇“配置屬性”→“VC++目錄” →“常規”,在右邊的“包含目錄”中添加C:\Program Files (x86)\Visual Leak Detector\include,其中C:\Program Files (x86)\Visual Leak Detector是我的vld安裝目錄。“庫目錄”中添加C:\Program Files (x86)\Visual Leak Detector\lib\Win32,注意配置目之間需要用分號分隔開。

 

配置完成之後點擊確定按鈕關閉對話框,然後我們需要在程序代碼中引入頭文件#include <vld.h>,但是這個頭文件在哪裡引入比較好?如果是普通的一個VC++工程在哪裡引入都無所謂,但是Cocos2d-x的工程就不同了,我們需要考慮跨平台,#include <vld.h>代碼不宜添加到Classes目錄下的h或cpp文件中,這個目錄下的文件是要在其它平台編譯運行的,而#include <vld.h>只是在Windrows平台才有效。我們可以在Win32目錄(見圖)下的main.cpp或main.h文件引入頭文件。這些文件是與Win32平台有關的,不同平台移植的時候不需要。

 

如果在main.cpp中引入代碼如下:

 

[html] view plaincopy在CODE上查看代碼片派生到我的代碼片  
  1. #include "main.h"  
  2. #include "AppDelegate.h"  
  3. #include "cocos2d.h"  
  4.    
  5. #include <vld.h>  
  6.    
  7. USING_NS_CC;  
  8.    
  9. int APIENTRY _tWinMain(HINSTANCE hInstance,  
  10.                        HINSTANCE hPrevInstance,  
  11.                        LPTSTR    lpCmdLine,  
  12.                        int       nCmdShow)  
  13. {  
  14.     UNREFERENCED_PARAMETER(hPrevInstance);  
  15.     UNREFERENCED_PARAMETER(lpCmdLine);  
  16.    
  17.     // create the application instance  
  18.     AppDelegate app;  
  19.     return Application::getInstance()->run();  
  20. }  

 

 

引入之後,就測試一下了,我們來人為制造一個內存洩漏,與20.1.1一節一樣在HelloWorldScene.cpp中修改代碼:

 

[html] view plaincopy在CODE上查看代碼片派生到我的代碼片  
  1. bool HelloWorld::init()  
  2. {  
  3. if ( !Layer::init() )  
  4. {  
  5. return false;  
  6. }  
  7.     __String *s = new __String();  
  8.    
  9.     log("%s",s->getCString());  
  10.    
  11. … …  
  12.    
  13. return true;  
  14. }  

 

 

運行工程,需要注意的是在程序運行過程中vld是沒有堆棧輸出的,但是日志會有輸出vld的安裝信息,日志信息如下:

Visual Leak Detector Version 2.4RC2 installed.

Ready for GLSL

Ready for OpenGL 2.0

… …

從日志中可以看到vld是否安裝成功,以及安裝的版本。要想看到vld檢測報告需要退出程序後,才會在日志中輸出信息。使用Cocos2d-x會輸出很多日志信息,信息如下: 

---------- Block 526166 at 0x0821FA80: 84 bytes ----------

  Leak Hash: 0x780B2033, Count: 1, Total 84 bytes

  Call Stack (TID 4660):

... ...

 

---------- Block 526214 at 0x08224378: 8 bytes ----------

  Leak Hash: 0xE1DC1852, Count: 1, Total 8 bytes

  Call Stack (TID 4660):

... ...

  Data:

    63 6F 63 6F    73 32 64 20    61 75 74 6F    72 65 6C 65     cocos2d. autorele

    61 73 65 20    70 6F 6F 6C    00 CD CD CD    CD CD CD CD     ase.pool ........

 

Visual Leak Detector detected 33 memory leaks (2892 bytes).

Largest number used: 3204961 bytes.

Total allocations: 69022415 bytes.

Visual Leak Detector is now exiting.

 

其中一個Block表示一個內存洩漏點,在眾多Block如果能夠找到關於我們自己類的日志信息呢?我們可以查找關鍵字“helloworldscene.cpp”,這就可以定位到HelloWorld場景中的內存洩漏的Block了,我們找到如下日志信息:

---------- Block 1153 at 0x01533C70: 48 bytes ----------

  Leak Hash: 0x5545A5ED, Count: 1, Total 48 bytes

  Call Stack (TID 2088):

    f:\dd\vctools\crt_bld\self_x86\crt\src\new.cpp (57): MSVCR110D.dll!operator new

    d:\helloworld\classes\helloworldscene.cpp (33): HelloWorld.exe!HelloWorld::init + 0x7 bytes

    d:\helloworld\classes\helloworldscene.h (37): HelloWorld.exe!HelloWorld::create + 0xB1 bytes

    d:\helloworld\classes\helloworldscene.cpp (12): HelloWorld.exe!HelloWorld::createScene + 0x5 bytes

    d:\helloworld\classes\appdelegate.cpp (30): HelloWorld.exe!AppDelegate::applicationDidFinishLaunching + 0x5 bytes

    d:\helloworld\cocos2d\cocos\2d\platform\win32\ccapplication.cpp (74): HelloWorld.exe!cocos2d::Application::run + 0xF bytes

    d:\helloworld\proj.win32\main.cpp (19): HelloWorld.exe!wWinMain + 0xC bytes

    f:\dd\vctools\crt_bld\self_x86\crt\src\crtexe.c (528): HelloWorld.exe!__tmainCRTStartup + 0x15 bytes

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

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

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

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

  Data:

    1C 34 07 01    01 00 00 00    27 00 00 00    00 00 00 00     .4...... '.......

    2C 34 07 01    A0 77 01 03    00 CD CD CD    CD CD CD CD     ,4...w.. ........

    CD CD CD CD    CD CD CD CD    00 00 00 00    0F 00 00 00     ........ ........

 

從這個日志中能看到內存洩漏點,從日志的堆棧中找到我們自己編寫的類,點擊那一行打開代碼窗口,定位內存洩漏點代碼,如圖所示。

 

定位內存洩漏點

 

找到哪一個有可能有內存洩漏,解決就不是問題了。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved