Detecting Memory Leaks

This article describes how to get the callstack for memory leaks in a certain component (EXE or DLL) of your Visual C++ program. The code provided with this article works on WindowsNT. It should work on Windows9x systems as well, although it has not been tested on such systems. There is another restriction, that it only works on Intel x86 machines. It has been written with MS Visual C/C++ 5.0, but it should work fine with Version 6 of the Developer Studio as well. The example program is written with the Active Template Library (ATL), but it does not contain any COM stuff.


To detect memory leaks in the components of your application, you just have to add the following lines anywhere to the code of your component:

	#include "c:\temp\HookAlloc\MemoryTracking.h"
	#pragma warning(disable:4073)							
	#pragma init_seg(lib)
  • the path in the #include-statement has to be adapted to your needs
  • The Macro USE_MEMORYTRACKING("c:\\temp\\allocations.log", bLogAtStartup) defines the name of the Logfile (if NULL, all output is written to the debug output window) and specifies, whether logging is on or off at program startup
  • To control the parts of your program where logging is on / off use the macros LOGGING_ON / LOGGING_OFF or BEGIN_NO_LOG_BLOCK / END_NO_LOG_BLOCK to switch off logging for a special part of code within a single function/method.
  • The pragma you see above switches off the stupid compiler warning that an 'initializer has been put in "lib" initialisation area'. This warning is not needed at all, since we know what we are doing with the next line: MemoryTracking is set up before any of the "users objects" (like MFC's CWinApp derived object) are initialized.

  • recompile your component (rebuild is NOT neccessary)
  • start your program, and invoke those parts of it, where the leaks occur
  • terminate the program and you'll get a list of memory leaks in your debug window of VC++
  • open the log file, that has been defined with the macro USE_MEMORYTRACKING (see above) or take a look into the VC++ debug output window, depending if you have defined a log filename or not
  • compare the numbers enclosed in curly braces (i.e. {1234} with the 'request'-numbers in the log file (or in the debug output window)

By looking at the call stack in the logfile, you may figure out which function or method has allocated the leak.


If MFC is used, you may add the line '#define new DEBUG_NEW' to the cpp files of the project. Thus you provide information about where allocations occur to the new operator. For allocations (leaks) that have been made with DEBUG_NEW defined you can simply double-click the line preceeding the call stack of a leak description (in the debug output window) to jump to the appropriate position in the source code.

  • Please note that this mechanism only works in Debug mode and that it severly affects the execution speed of your program. This code has not been developed to be included permanently in your code, it should only be used to detect memory leaks.
  • Please not that the code can detect only those leaks that are caused in the component (DLL, OCX, EXE, ...) where tracking is enabled. Tracking can only be enabled for one single component.


    Download demo project - 11 Kb

  • Comments

    • Doesn't work

      Posted by Legacy on 12/18/2002 12:00am

      Originally posted by: Maciej Misiak

      I think this should be little quicker... I started my server application and waited 20 minutes. Memory use has grown from 5MB to 125MB (ca. 100kB/sec.) and didn't want to stop grow. I killed this process. Without this MemoryLeakFinder it starts in 10 secs.

    • some help...

      Posted by Legacy on 11/13/2002 12:00am

      Originally posted by: David Huelves Ramos

      I you have memory leaks:

      1) first take note of the address of the memory that is not free when program finish
      2)then open the memory spy (from debug toolbar inside VC++ environment) stop the program in debug mode at the beginning.
      3)set the memory spy to the address location u got on step "1)".
      4) go step by step until this memory possition is filled.

      5)then you know which part of your program is filling it, so you have to look why it doesn't free it when the program finish.

      hope this helps.

      remember to free all allocated memory using destructors...

    • Doesn't catch 'COM-type" leaks

      Posted by Legacy on 04/30/2002 12:00am

      Originally posted by: Robin


      I just gave this a try and it works, but only to an extent. It doesn't catch the types of leaks you're most likely to see in a COM/ATL component. For example, I added the following pieces of code to test MemoryTracker:

      int* pNum = new int(3);
      BSTR dbgStr = SysAllocString(L"Pokey & Gumby");
      int* pNum2 = (int*)CoTaskMemAlloc(7);

      It caught the 1st one but did not catch the other two. This is the same problem as when attempting to use the _CrtMem functions (e.g. _CrtMemCheckpoint, etc) :-(


    • A simpler way...

      Posted by Legacy on 04/16/2002 12:00am

      Originally posted by: rui costa

      I think I've got a better way to detect memory leaks: the _CrtSetDbgFlag function.
      It's provided by the windows API, it's easy to use and very safe.

      You just need to call CrtSetDbgFlag anywhere in your code !
      Here is a simple:

      #include <crtdbg.h>

      #ifdef _DEBUG
      #define new new(_NORMAL_BLOCK, THIS_FILE, __LINE__)
      #undef THIS_FILE
      static char THIS_FILE[] = __FILE__;

      void main()

      char* memory_leak = new char[256];

      And that's all !

      If your program has memory leaks, you'll be informed at the end of the program execution.
      Check in the debug window for errors.
      If you have errors, double click over the error message and you'll know the line where your program has allocated the memory.

      If you need more specific information, you can use this class:

      class FindMemoryLeaks
      _CrtMemState m_checkpoint;



      _CrtMemState checkpoint;

      _CrtMemState diff;
      _CrtMemDifference(&diff, &m_checkpoint, &checkpoint);


      Put it in the beginning of your program.
      Good look !

    • memory leaks

      Posted by Legacy on 03/21/2002 12:00am

      Originally posted by: S.Senthil Kumar

      i was looking for this code Thanks i will use it hereafter

    • Memory Leak Problem

      Posted by Legacy on 02/08/2002 12:00am

      Originally posted by: Kalpesh

      Thanks a lot for valuable information on this site.
      However, I haven't got exact solution to my problem.
      My server application keeps on consuming memory, and when i gracefully shutdown the server, i dont see any memory leaks in debug window. But looking at the process table, i'm sure that my server is idling, but still keeps on increasing 4K every minute or so.
      Can you guide me to find such problem?

    • error C2664

      Posted by Legacy on 01/21/2002 12:00am

      Originally posted by: Anonymous

      I added your code at the top of my code:
      #include "c:\\foo\\MemoryTracking.h"
      #pragma warning(disable:4073)
      #pragma warning(disable:4786)
      #pragma init_seg(lib)

      But I get this error message:
      c:\\foo\\memorytracking.h(279) : error C2664: '_CrtSetAllocHook' : cannot convert parameter 1 from 'int (__cdecl *)(int,void *,unsigned int,int,long,const char *,int)' to 'int (__cdecl *)(int,void *,unsigned int,int,long,const unsigned char *,int)'
      This conversion requires a reinterpret_cast, a C-style cast or function-style cast

      What am I doing wrong???

    • This is a very neat tool.

      Posted by Legacy on 09/19/2001 12:00am

      Originally posted by: Vicky Wallace


    • [Question] file name and line number were not dsiplayed.

      Posted by Legacy on 04/03/2001 12:00am

      Originally posted by: Seung-Hoon Lee

      Hi, users.

      I am Seung-Hoon Lee. When I read this article, I was excite.
      So, I ran this sample and got a below log file.

      As seen as you read the below log, I didn't get the detail file name and line number that the memory leak happened.

      Could you help me make the file name and line number display ?



      Alloc: request=49, size=100, blocktype=_NORMAL_BLOCK, file=(null), line=0
      C:\WINNT\System32\ntdll.dll section: 1 offset: 181
      operator new +14 bytes sig: ??2@YAPAXI@Z decl: void * __cdecl operator new(unsigned int)
      _Function +16 bytes sig: _Function decl: _Function
      _WinMain@16 +85 bytes sig: _WinMain@16 decl: _WinMain@16
      _WinMainCRTStartup +275 bytes sig: _WinMainCRTStartup decl: _WinMainCRTStartup
      SetStdHandle +22 bytes sig: SetStdHandle decl: SetStdHandle
      Alloc: request=50, size=50, blocktype=_NORMAL_BLOCK, file=(null), line=0
      C:\WINNT\System32\ntdll.dll section: 1 offset: 181
      operator new +14 bytes sig: ??2@YAPAXI@Z decl: void * __cdecl operator new(unsigned int)
      ThreadProc +16 bytes sig: ?ThreadProc@@YGKPAX@Z decl: unsigned long __stdcall ThreadProc(void *)
      RegisterConsoleVDM +519 bytes sig: RegisterConsoleVDM decl: RegisterConsoleVDM
      Number of Memory Leaks in Module: 2

    • Detecting memory leaks.

      Posted by Legacy on 01/24/2001 12:00am

      Originally posted by: Howard Harvey

      While Stefan does do an admirable job of showing
      how to catch memory leaks, my personal favorite
      tool for the job is still BoundsChecker by
      NuMega/Compuware. Just personal preference.

    • Loading, Please Wait ...

    Leave a Comment
    • Your email address will not be published. All fields are required.

    Top White Papers and Webcasts

    • Anthony Christie, the Chief Marketing Officer for Level Communications, is responsible for customer experience, worldwide marketing and product management. In this informative asset, he shares his insights into why a private network connection to cloud-bases applications is the right decision for your enterprise. Download now to find out more.

    • Moving from an on-premises environment to Office 365 does not remove the need to plan for disruptions or reduce the business risk requirements for protecting email services. If anything, some risks increase with a move to the cloud. Read how to ease the transition every business faces if considering or already migrating to cloud email. This white paper discusses: Setting expectations when migrating to Office 365 Understanding the implications of relying solely on Exchange Online security Necessary archiving …

    Most Popular Programming Stories

    More for Developers

    RSS Feeds

    Thanks for your registration, follow us on our social networks to keep up-to-date