Search code examples
c++windowsmemory-leaksqt-creatordetect

How to detect memory leaks in QtCreator on Windows?


How can I detect memory leaks in QtCreator on Windows? On the doc, they recommend Memcheck but it only works on Mac and Linux. Any suggestion for Windows?


Solution

  • After many tries I finally found a method to detect the memory leaks of a Qt project on Windows:

    1) First, it cannot be done directly in Qt Creator so you need to create a Visual C++ project to do the memory leak detection. Thankfully, qmake makes this easy. Open the Qt SDK command line tool and run:

    qmake -spec win32-msvc2008 -tp vc
    

    This will convert your project to a .vcproj.

    2) Open this project and add the necessary code for memory leak detection:

    To your main.cpp file:

    // Necessary includes and defines for memory leak detection:
    #ifdef _MSC_VER
    #define _CRTDBG_MAP_ALLOC
    #include <crtdbg.h>
    #endif // _MSC_VER
    
    
    #if defined(_MSC_VER)
    
    // Code to display the memory leak report
    // We use a custom report hook to filter out Qt's own memory leaks
    // Credit to Andreas Schmidts - http://www.schmidt-web-berlin.de/winfig/blog/?p=154
    
    _CRT_REPORT_HOOK prevHook;
    
    int customReportHook(int /* reportType */, char* message, int* /* returnValue */) {
      // 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(message,"Detected memory leaks!\n", 10) == 0)
        || ignoreMessage)
      {
        // check if the memory leak reporting ends
        if (strncmp(message,"Object dump complete.\n", 10) == 0)
        {
          _CrtSetReportHook(prevHook);
          ignoreMessage = false;
        } else
          ignoreMessage = true;
    
        // something from our own code?
        if(strstr(message, ".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;
    }
    
    #endif
    
    
    
    int main(int argc, char *argv[]) {
        #if defined(_MSC_VER)
        _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
        prevHook = _CrtSetReportHook(customReportHook);
        // _CrtSetBreakAlloc(157); // Use this line to break at the nth memory allocation
        #endif
    
        QApplication* app = new QApplication(argc, argv);   
        int appError = app->exec();
        delete app;
    
        #if defined(_MSC_VER)
        // Once the app has finished running and has been deleted,
        // we run this command to view the memory leaks:
        _CrtDumpMemoryLeaks();
        #endif 
    
        return appError;
    }
    

    3) With this, your project should now be able to detect memory leaks. Note the _MSC_VER defines so that this code is only executed when your run it from Visual C++ (not from Qt Creator). It means you can still do the development with Qt Creator and just re-run step 1 whenever you need to check for memory leaks.

    4) To break at a particular memory allocation, use _CrtSetBreakAlloc() More information memory leak detection on Microsoft's website: http://msdn.microsoft.com/en-us/library/e5ewb1h3%28v=vs.80%29.aspx