Click here to Skip to main content
15,353,676 members
Articles / Programming Languages / C++
Posted 3 Oct 2004


217 bookmarked

Memory Leak Detection

Rate me:
Please Sign up or sign in to vote.
4.71/5 (55 votes)
3 Jul 2009CPOL7 min read
Adding Memory Leak Detection in your applications

Image 1


OK, So you want a memory leak detector and don't want to pay thru the nose for it! You've gone ahead and read all the articles on Memory Leak Detection (whew!!) and are totally confused and frustrated with all the technical details on how to hook memory, walk a stack, display symbols and still get the performance you need to run your application. You've Looked at lots of code and found that it's kind of a big mess to add your own memory leak detection. Well I hope that I can help out and clear the air. I have managed to create a single class that you can add to your code and find those pesky memory leaks. You can do this in debug mode or final release mode and customize your own memory leak detection.


Ok, I worked for a big corporation and demanded they buy me all those expensive development toys :-) such as memory leak detection tools that I needed. Who cares how much it costs, I said! It's worth every penny! You don't want your application crashing on your customer premises do you? You don't want to consume our clients computing resources do ya? How embarrassing that would be being a top software development company? Well that was all good and said until I left that big corporation and started my own company! Wow those development tools I needed are sure expensive! But the fact is I must have a memory leak detector to make my applications bullet proof. To give me the confidence that my application is working at it's best! Not that I write leaky code or anything, ooooh Nooooo not me :-(. I point the finger at all the other people that I link into my code. From poorly or undocumented API's to complex source code I'd rather not look at. It's their fault for not telling me to free this or free that or delete this or delete that. hmmm. But it's my fault if I don't even check my application before I distribute it to others and it's eats all their memory!

There's no excuse to have leaky apps, your reputation is on the line, you need to test your applications and make sure they are not leaking and consuming unnecessary resources.

Before you Use the Code

Make sure that the dbghelp.dll file is an up to date version or later. You can distribute this file with your application if you wish. If you don't know where to get this file you can download it from the Microsoft site

Using the code

CMemLeakDetect() class is the only class you need to worry about. In your code just include the "MemLeakDetect.h" file and then create a global instance of the class with CMemLeadDetect memLeakDetect;

This has the effect of catching any memory leaks that are present in your application before "theApp" starts execution and after it has exited. It will also work for non-MFC apps, Win32 apps, Console Apps. It's too easy! Well isn't that what it's all about! Making your life easier?

// MFCLeakerTest.cpp : Defines the class behaviors for the application.

#include "stdafx.h"
#include "MFCLeakerTest.h"
#include "MFCLeakerTestDlg.h"
#include "MemLeakDetect.h"

// CMFCLeakerTestApp


// CMFCLeakerTestApp construction

 CLeakMemory* pMem;

 pMem = new CLeakMemory();

 // TODO: add construction code here,
 // Place all significant initialization in InitInstance

// Detect Memory Leaks
#ifdef _DEBUG
CMemLeakDetect memLeakDetect;

// The one and only CMFCLeakerTestApp object

CMFCLeakerTestApp theApp;

// CMFCLeakerTestApp initialization

BOOL CMFCLeakerTestApp::InitInstance()
 // InitCommonControls() is required on Windows XP if an application
 // manifest specifies use of ComCtl32.dll version 6 or later to enable
 // visual styles.  Otherwise, any window creation will fail.



Understanding the Code

This class really looks pretty straight forward. The public methods are very simple to understand. Init() initializes the CMemLeadDetect class. End() does the memory report of unfreed memory when the destructor method is called. AddMemoryTrace() - is when an alloc memory orcurrs, RemoveMemoryTrace() - is a free memory event, RedoMemoryTrace() - is a re-alloc memory event. I must point out that the fileName is limited to MLD_MAX_NAME_LENGTH(256) characters. If you anticipate more than this as a file name then please increase this limit. Also the same for traceinfo MLD_MAX_TRACEINFO(256) . This means that if you expect that there will be more than 256 functions deep when a memory allocation occurs then by all means increase this limit also. Personally I've seen it go to 230 entries but it was really unusual but not impossible. I would say that 256 entries is kind of ordinary but 512 entries is very large. Somewhere in between maybe good but it's up to you.

The AllocBlockInfo() class is a sub-class of CMemLeakDetect() because this is what keeps track of all of the allocations and free's. It's indexed by the request number that allocates, reallocates or frees memory in a CMap list which is a hash list. Because it's a hash list it's important to initialize it so that all the allocations in the hash list are done before the application initializes. This will keep your application from being sluggish with the CMemLeakDetect. But don't just stick any number in the hash list because you can seriously degrade a hash list performance if it starts dividing even slots which in turn are called collisions. To avoid these collisions (as many as we can) it's best to initialize it with a prime number such as AllocatedMemoryList.InitHastTable(10211, TRUE) as I have done. When your application ends and the memory report dumps all the unfreed memory and a summary you will see a total allocations that occurred in your application. If you have more than a total of 10211 allocations you should bump up the prime number to the one that is more than your maximum. If you want more entries find a bigger prime number. This pre-allocation of hash table entries will help your performance tremendously during runtime. The STACKFRAMEENTRY is a structure that is an array of traceinfo starting at location [0] which is always the CMemLeakDetect() methods and it walks the stack to all the callers that exist on the stack [1], [2].... and so on. The last traceinfo entry is [n] = 0;

#define MLD_MAX_NAME_LENGTH   256
#define MLD_MAX_TRACEINFO   256

typedef struct _STACKFRAMEENTRY
  ADDRESS   AddrFrame;

class CMemLeakDetect
  class AllocBlockInfo
    inline AllocBlockInfo() {};
    inline ~AllocBlockInfo() {};
    inline AllocBlockInfo(AllocBlockInfo& abi)
     address  = abi.address;
     size  = abi.size;
     lineNumber = abi.lineNumber;
     occurance = abi.occurance;
     memcpy(&traceinfo[0], &abi.traceinfo[0], sizeof(traceinfo));
     memcpy(fileName, abi.fileName, sizeof(fileName));

   void*    address;
   DWORD    size;
   char    fileName[MLD_MAX_NAME_LENGTH];
   DWORD    lineNumber;
   DWORD    occurance;

  void Init();
  void End();
  void addMemoryTrace(void* addr,  DWORD asize,  char *fname, DWORD lnum);
  void redoMemoryTrace(void* addr,  void* oldaddr, 
   DWORD asize,  char *fname, DWORD lnum);
  void removeMemoryTrace(void* addr);
  void cleanupMemoryTrace();
  void dumpMemoryTrace();

 CMap< LPVOID, LPVOID, AllocBlockInfo, AllocBlockInfo > m_AllocatedMemoryList;
 DWORD memoccurance;
 bool  isLocked;

  BOOL initSymInfo(char* lpUserPath);
  BOOL cleanupSymInfo();
  void symbolPaths( char* lpszSymbolPaths);
  void symStackTrace(STACKFRAMEENTRY* pStacktrace);
  BOOL symFunctionInfoFromAddresses(ULONG fnAddress,
   ULONG stackAddress, char* lpszSymbol);
  BOOL symSourceInfoFromAddress(UINT address, char* lpszSourceInfo);
  BOOL symModuleNameFromAddress(UINT address, char* lpszModule);

  HANDLE    m_hProcess;
  DWORD    m_dwsymBufSize;

The private members are more interesting because that is where a lot of the tricky work has been done! My goal was the keep all the sym* routines as simple as possible and I tried not to do too many system calls. symStackTrace() is the function that captures the stack at the time of any memory operation.

Points of Interest

catchMemoryAllocHook() this is a memory hook routine which is the at the heart of this CMemDetect class. It's where the most complex and convoluted part of the code is. Documentation on this area is sparse and mostly undocumented by our friends at Microsoft. I'm not even sure I have caught all the situations. If there's going to be a major bug it's most likely going to show up here. Also I'm only using a simple locking mechanism because I didn't want to do any system calls for a Critical Section, Semaphores, or CSimpleLock. All the documentation I read says that only one thread can access this memory hook at a time and it reentrant safe! Based on that premise I just used the simplest mechanism.


I must give credit to Code Glow for the inspiration because I didn't want to pay for it at $299.00 US (a fair price though), Compuware Corporation again too expensive for my cheap budget! :-) so I wrote my own. Thanks to Erwin Andreasen <erwin>& Henner Zeller for LeakTracer Johan Lindh for MemWatch <h.zeller>R. Walker and Jochen Kalmbach in which I found inspiration to provide my own. I did a lot of research and found an overwhelming amount of information on the subject but nothing was done in a comprehensive and clear manner. So finally I give credit to myself :-) for all the late nights and hard work getting this class all debugged and cleaned up for this article. :-)


  • Initial Version July 30, 2004, by David A. Jones
  • Added Non MFC Version October 6, 2004, by David A. Jones
  • Fixed User Issues October 11, 2004 by David A. Jones
    • fixed buffer overruns now using MLD_MAX_NAMELEN
    • add symStackTrace2 that is an alternative to StackWalker64(), in non-MFC version & untested
    • fixed up some lint issues in both versions
  • Update October 18, 2004 by David A. Jones
    • added an alternative stackwalker using MLD_CUSTOMSTACKWALK to select which stackwalker to compile
    • consolidated the MFC version and the non MFC version. They are both the same code now
    • fixed more UNICODE issues, should be UNICODE compliant


This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


About the Author

David A. Jones
Web Developer
Canada Canada
No Biography provided

Comments and Discussions

Questionthanks but how can i get this work on Visual studio 2013? Pin
liewjen7-Sep-17 5:15
Memberliewjen7-Sep-17 5:15 
AnswerRe: thanks but how can i get this work on Visual studio 2013? Pin
Southmountain31-Jan-20 6:37
MemberSouthmountain31-Jan-20 6:37 
Questionthank you Pin
Www_MemoryLeak9-Jun-15 15:51
MemberWww_MemoryLeak9-Jun-15 15:51 
QuestionThank you DAJ when it can support MFC Pin
Www_MemoryLeak24-May-15 23:12
MemberWww_MemoryLeak24-May-15 23:12 
QuestionProblems in VS 2010 Pin
Haris Anwer24-Mar-14 18:14
MemberHaris Anwer24-Mar-14 18:14 
AnswerRe: Problems in VS 2010 Pin
Tim Stevens28-Mar-14 2:08
MemberTim Stevens28-Mar-14 2:08 
QuestionHow to use realese mode? Pin
Saviovt1015-Oct-12 20:51
MemberSaviovt1015-Oct-12 20:51 
QuestionDEBUG_NEW MFC macro does the same memory leak detection Pin
steveb9-Feb-12 11:18
Membersteveb9-Feb-12 11:18 
QuestionVerry Nice Pin
elgaabeb22-Nov-11 23:00
Memberelgaabeb22-Nov-11 23:00 
SuggestionVisual Studio 2003 compile error Pin
Adorjáni Alpár11-Nov-11 9:10
MemberAdorjáni Alpár11-Nov-11 9:10 
GeneralCongrats Pin
Member 82371437-Oct-11 4:50
MemberMember 82371437-Oct-11 4:50 
GeneralIt is a perfect project. Pin
dev3d8-May-11 22:58
Memberdev3d8-May-11 22:58 
GeneralDestructor bailing on deleting when including memleakdetect.h Pin
knogas4-May-11 13:55
Memberknogas4-May-11 13:55 
GeneralRe: Destructor bailing on deleting when including memleakdetect.h Pin
Doug Rogers6-May-11 13:43
MemberDoug Rogers6-May-11 13:43 
GeneralRe: Destructor bailing on deleting when including memleakdetect.h Pin
knogas9-May-11 13:20
Memberknogas9-May-11 13:20 
GeneralRe: Destructor bailing on deleting when including memleakdetect.h Pin
Philippe Mori1-Oct-11 4:43
MemberPhilippe Mori1-Oct-11 4:43 
GeneralMy vote of 5 Pin
Nirav Doshi11-Mar-11 2:37
MemberNirav Doshi11-Mar-11 2:37 
GeneralThis is PERFECT Pin
rob_toutant3-Mar-11 12:53
Memberrob_toutant3-Mar-11 12:53 
GeneralNew version of this code is now a CodeProject Tip article [modified] Pin
Tim Stevens23-Feb-11 22:21
MemberTim Stevens23-Feb-11 22:21 
GeneralMemLeakDetect updated for Win64 Pin
Doug Rogers5-Feb-11 11:02
MemberDoug Rogers5-Feb-11 11:02 
GeneralRe: MemLeakDetect updated for Win64 Pin
Tim Stevens23-Feb-11 22:22
MemberTim Stevens23-Feb-11 22:22 
GeneralBugfix Pin
User 345557713-Sep-10 3:01
MemberUser 345557713-Sep-10 3:01 
Questionhow can i use to detect buffer over run Pin
sachin_m24-Jun-10 0:42
Membersachin_m24-Jun-10 0:42 
AnswerRe: how can i use to detect buffer over run Pin
Tim Stevens24-Jun-10 9:13
MemberTim Stevens24-Jun-10 9:13 
GeneralDetecting Memory leak in Visual Studio (Debug mode) Pin
elizas3-Feb-10 23:19
Memberelizas3-Feb-10 23:19 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.