Qt在VS中的内存泄露检测
今天在QT_VP中简单地添加了内存泄露检测语句:
_CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
结果出来一大堆的内存泄露,着实吓了一跳,跟踪了一天,逐段派出,最后还是感觉没问题(还是比较自信代码质量的O(∩_∩)O哈哈~)。。。最后上网一查,在vs中,先是进行内存泄露报告,然后才卸载Qt的dll,释放申请的资源。所以才会出现这种情况。
标志内存检测报告: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
在cpp中添加该头文件以后,内存泄露报告格式:
- ./mainwindow.cpp(530) : {24737} client block at 0x00C12420, subtype 0, 8 bytes long.
- ./mainwindow.cpp(367) : {6653} client block at 0x00B59E68, subtype 0, 8 bytes long.
然后在main函数中添加一个内存报告过滤器,将不是"*.cpp"格式的报告过滤掉,即可~
过滤器头文件reportinghook.h:
- #pragma once
- #if defined(WIN32)
- void setFilterDebugHook(void);
- #endif
reportinghook.cpp:
- #if defined(WIN32)
- #include <string.h>
- #include "crtdbg.h"
- #define FALSE 0
- #define TRUE 1
- _CRT_REPORT_HOOK prevHook;
- int reportingHook(int reportType, char* userMessage, int* retVal)
- {
- // This function is called several times for each memory leak.
- // Each time a part of the error message is supplied.
- // This holds number of subsequent detail messages after
- // a leak was reported
- const int numFollowupDebugMsgParts = 2;
- static bool ignoreMessage = false;
- static int debugMsgPartsCount = 0;
- // check if the memory leak reporting starts
- if ((strncmp(userMessage,"Detected memory leaks!/n", 10) == 0)
- || ignoreMessage)
- {
- // check if the memory leak reporting ends
- if (strncmp(userMessage,"Object dump complete./n", 10) == 0)
- {
- _CrtSetReportHook(prevHook);
- ignoreMessage = false;
- } else
- ignoreMessage = true;
- // something from our own code?
- if(strstr(userMessage, ".cpp") == NULL)
- {
- if(debugMsgPartsCount++ < numFollowupDebugMsgParts)
- // give it back to _CrtDbgReport() to be printed to the console
- return FALSE;
- else
- return TRUE; // ignore it
- } else
- {
- debugMsgPartsCount = 0;
- // give it back to _CrtDbgReport() to be printed to the console
- return FALSE;
- }
- } else
- // give it back to _CrtDbgReport() to be printed to the console
- return FALSE;
- };
- void setFilterDebugHook(void)
- {
- //change the report function to only report memory leaks from program code
- prevHook = _CrtSetReportHook(reportingHook);
- }
- #endif
测试程序:
- #include "setdebugnew.h"
- #include "reportingHook.h"
- int main(int argv, char *args[])
- {
- _CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
- QApplication app(argv, args);
- MainWindow* mainWindow = new MainWindow;
- mainWindow->setGeometry(30, 30, 1024, 768);
- mainWindow->show();
- app.connect( &app, SIGNAL(lastWindowClosed()), &app, SLOT(quit()) );
- int result = app.exec();
- #if defined(WIN32) && defined(_DEBUG)
- setFilterDebugHook();
- #endif
- return result ;
- }