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.
Usage
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"
USE_MEMORYTRACKING("c:\\temp\\allocations.log",true)
#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.
Then:
- 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.
Tip:
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.

Comments
Doesn't work
Posted by Legacy on 12/18/2002 12:00amOriginally 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.
Reply
some help...
Posted by Legacy on 11/13/2002 12:00amOriginally posted by: David Huelves Ramos
ReplyDoesn't catch 'COM-type" leaks
Posted by Legacy on 04/30/2002 12:00amOriginally posted by: Robin
ReplyA simpler way...
Posted by Legacy on 04/16/2002 12:00amOriginally posted by: rui costa
Replymemory leaks
Posted by Legacy on 03/21/2002 12:00amOriginally posted by: S.Senthil Kumar
i was looking for this code Thanks i will use it hereafter
ReplyMemory Leak Problem
Posted by Legacy on 02/08/2002 12:00amOriginally posted by: Kalpesh
Hi,
ReplyThanks 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?
Thanks,
Kalpesh
error C2664
Posted by Legacy on 01/21/2002 12:00amOriginally posted by: Anonymous
I added your code at the top of my code:
-------------//-----------
#include "c:\\foo\\MemoryTracking.h"
USE_MEMORYTRACKING(MT,"c:\\foo\\allocs.log")
#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???
ReplyThis is a very neat tool.
Posted by Legacy on 09/19/2001 12:00amOriginally posted by: Vicky Wallace
Thanks
Reply[Question] file name and line number were not dsiplayed.
Posted by Legacy on 04/03/2001 12:00amOriginally 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 ?
.....
[allocs.txt]
Alloc: request=49, size=100, blocktype=_NORMAL_BLOCK, file=(null), line=0
ReplyC:\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:00amOriginally posted by: Howard Harvey
While Stefan does do an admirable job of showing
Replyhow to catch memory leaks, my personal favorite
tool for the job is still BoundsChecker by
NuMega/Compuware. Just personal preference.
Loading, Please Wait ...