vld-2.2.3: ​​http://vld.codeplex.com/releases/view/82311​


 


方法一:



参考链接2: ​​http://www.schmidt-web-berlin.de/winfig/blog/?p=154​


参考链接1参考链接2说的是一个东西,不使用任何工具,自己写程序判断溢出位置。



方法二:



参考链接4: ​​http://hi.baidu.com/sunchongjing/blog/item/cd1920faf61ee7d3b48f3108.html​


参考链接3参考链接4是用VLD(Visual Leak Detector)来检测内存溢出,当然更加专业。



问题描述:


今天在QT_VP中简单地添加了内存泄露检测语句:


_CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );


结果出来一大堆的内存泄露,着实吓了一跳,跟踪了一天,逐段派出,最后还是感觉没问题(还是比较自信代码质量的O(∩_∩)O哈哈~)。。。最后上网一查,在vs中,先是进行内存泄露报告,然后才卸载Qt的dll,释放申请的资源。所以才会出现这种情况。



系统环境:

windows7 + VS2008;



方法一:


操作方法与参考链接1做法一致,如下:


标志内存检测报告:setdebugnew.h(注意,只有在cpp中添加setdebugnew.h,而且有new操作的那些函数或者类被调用,才会进行内存泄露跟踪)



#ifndef SET_DEBUG_NEW_H


#define SET_DEBUG_NEW_H


 


#ifdef _DEBUG


#define DEBUG_CLIENTBLOCK   new( _CLIENT_BLOCK, __FILE__, __LINE__)


#else


#define DEBUG_CLIENTBLOCK


#endif


 


#define _CRTDBG_MAP_ALLOC


#include <crtdbg.h>


 


#ifdef _DEBUG


#define new DEBUG_CLIENTBLOCK


#endif


 


#endif // end SET_DEBUG_NEW_H


 


在需要检测的cpp文件中包含setdebugnew.h头文件


test_memoryleak.cpp



#include "test_memoryleak.h"


#include <QtGui>


 


#include "setdebugnew.h"


 


test_memoryLeak::test_memoryLeak(QWidget *parent, Qt::WFlags flags)


      : QWidget(parent, flags)


{


      btn1 = new QPushButton("test1", this);


      btn2 = new QPushButton("close", this);


 


      QWidget *memLeak_test = new QWidget;


 


      connect(btn2, SIGNAL(clicked()), this, SLOT(close()));


 


      QHBoxLayout *layout = new QHBoxLayout;


 


      layout->addWidget(btn1);


      layout->addWidget(btn2);


 


      setLayout(layout);


}


 


test_memoryLeak::~test_memoryLeak()


{


 


}


 


main.cpp(在主函数入口处设置_CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );)



#include "test_memoryleak.h"


#include <QtGui/QApplication>


 


#include "setdebugnew.h"


 


int main(int argc, char *argv[])


{


#ifdef _DEBUG 


      _CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );


#endif


 


      int *i = new int;


 


      QApplication a(argc, argv);


      test_memoryLeak w;


      w.show();


      return a.exec();


}


 


启动调试,在程序运行结束后,查看“输出”项中的内容



{1220} normal block at 0x016605F8, 552 bytes long.


 Data: <          f     > 83 00 00 00 83 00 00 00 08 06 66 01 CD CD CD CD


{1215} normal block at 0x01660398, 292 bytes long.


 Data: <   eH f      x=g> 94 85 A2 65 48 03 66 01 00 00 00 00 C4 78 3D 67


.\test_memoryleak.cpp(12) : {1214} client block at 0x01660348, subtype 0, 20 bytes long.


.


.


.



{289} normal block at 0x01388960, 56 bytes long.


 Data: <      8         > 03 00 00 00 88 8A 38 01 00 CD CD CD 00 00 00 00


.\main.cpp(12) : {285} client block at 0x013872B0, subtype 0, 4 bytes long.


 Data: <    > CD CD CD CD


Object dump complete.


 


黑体加粗部分的才是程序真正溢出的地方。




方法二:

使用VLD检测内存溢出,VLD下载地址: ​​http://vld.codeplex.com/releases/view/82311​​(2.2.3版只支持VS2008/2010 )


安装过程会弹出如下对话框,


QT VS检测内存泄漏_#endif


新版解决了path问题,所以我们无需做过多的设置。


 


安装完成后,还需要对VS的编译路径进行设置,


在“工具”->“选项”->”项目和解决方案“->"VC++目录" 添加VLD的”包含文件“路径和”库文件“路径,如下如所示:


QT VS检测内存泄漏_#endif_02


注意:参考链接4提到了,在win7中需要拷贝dbghelp.dll和vdl_x86.dll到system32目录,而我在配置的时候并不需要这么做。


 


在main.cpp中包含vld.h头文件即可,如下:



#include "test_memoryleak.h"


#include <QtGui/QApplication>


 


#ifdef _DEBUG 


#include "vld.h" 


#endif


 


#include "setdebugnew.h"


 


 


int main(int argc, char *argv[])


{


#ifdef _DEBUG 


      _CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );


#endif


 


      int *i = new int;


 


      QApplication a(argc, argv);


      test_memoryLeak w;


      w.show();


      return a.exec();


}


 


启动调试,在程序运行结束后,查看“输出”项中的内容



WARNING: Visual Leak Detector detected memory leaks!


---------- Block 1 at 0x007F72B0: 4 bytes ----------


  Call Stack:


    c:\users\ajaxhe\desktop\program\qt\practice\test_memoryleak\test_memoryleak\main.cpp (17): test_memoryLeak.exe!main + 0x10 bytes


    C:\Qt\4.7.4\src\winmain\qtmain_win.cpp (131): test_memoryLeak.exe!WinMain + 0x12 bytes


    f:\dd\vctools\crt_bld\self_x86\crt\src\crtexe.c (578): test_memoryLeak.exe!__tmainCRTStartup + 0x35 bytes


    f:\dd\vctools\crt_bld\self_x86\crt\src\crtexe.c (403): test_memoryLeak.exe!WinMainCRTStartup


    0x76B9ED6C (File and line number not available): kernel32.dll!BaseThreadInitThunk + 0x12 bytes


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


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


  Data:


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


 


 


---------- Block 4 at 0x00CA0348: 20 bytes ----------


  Call Stack:


    c:\users\ajaxhe\desktop\program\qt\practice\test_memoryleak\test_memoryleak\test_memoryleak.cpp (12): test_memoryLeak.exe!test_memoryLeak::test_memoryLeak + 0x10 bytes


    c:\users\ajaxhe\desktop\program\qt\practice\test_memoryleak\test_memoryleak\main.cpp (20): test_memoryLeak.exe!main + 0x17 bytes


    C:\Qt\4.7.4\src\winmain\qtmain_win.cpp (131): test_memoryLeak.exe!WinMain + 0x12 bytes


    f:\dd\vctools\crt_bld\self_x86\crt\src\crtexe.c (578): test_memoryLeak.exe!__tmainCRTStartup + 0x35 bytes


    f:\dd\vctools\crt_bld\self_x86\crt\src\crtexe.c (403): test_memoryLeak.exe!WinMainCRTStartup


    0x76B9ED6C (File and line number not available): kernel32.dll!BaseThreadInitThunk + 0x12 bytes


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


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


  Data:


    04 7C FB 00    98 03 CA 00    E0 7B FB 00    00 00 CD CD     .|...... .{......


    50 04 CA 00                                                  P....... ........


 


 


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


Largest number used: 260 bytes.


Total allocations: 260 bytes.


Visual Leak Detector is now exiting.


 


溢出位置与预期一致!