Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Mobile / WinMobile

Memory Leak Detector for C++

3.24/5 (9 votes)
14 Dec 20064 min read 1   1.6K  
Simple plug-in code for debugging memory leaks.

Introduction

This simple standalone memory leak detector plugs right into your C++ project, and can be turned on by simply defining DEBUG_MEMORY in your project's preprocessor setting or in your makefile, and calling DumpUnfreed(TRUE); at the end of your program to create a memoryleak.txt file when your program exits. You can also call DumpUnfreed() at strategic locations within your program. This code is very portable, and will run in any Windows, Linux, or DOS environment. It has also been tested in the Linux environment for the GCC 3.2.2 compiler and on Win32 using Developer Studio 1.1. The DebugMemory routines override malloc(), calloc(), free(), delete(), new(), delete[], and new[]. The memoryleak.txt file prints out the file and line number and the file name where the allocation took place, as well as the address of the buffer allocated and its size. Any addresses that are freed through DebugMemory that were not allocated through DebugMemory are also noted in the memoryleak.txt output file.

In addition to creating a memory leak report, you can trace every allocation and deallocation in your code by placing a call to DebugMemoryLogAllocations(TRUE); at the beginning of your program. This will create a file called debugmemorylog.txt that shows every allocation and deallocation that runs through the DebugMemory interfaces. The additional logging does slow down your program significantly, so this feature is not suitable for real-time applications.

Using the Samples

Included in the zip are two additional zip files that have samples that test the various new / delete, malloc, calloc, and free overrides. GCCSample.zip includes a Linux sample with a makefile, and Win32Sample.zip includes a Windows Developer Studio 1.1 sample project. The sample demonstrates allocating standard memory chunks through malloc, calloc, and deallocating those chunks via free. It also shows allocating a C++ class as a single object, and an array of class objects. The class constructor also allocates memory via new, and deletes that memory in its destructor. In addition, it shows a derived class that instantiates the base class, plus the derived class allocates memory in its own constructor for members local to the derived class. The derived class is allocated as a single object and also as an array of objects in the sample code. You can walk through the allocations using the Visual Studio debugger and watch how the memory allocation system works.

The sample program source is identical for both operating systems, and produces a debugmemorylog.txt trace file of each allocation and deallocation, as well as a memoryleak.txt output file. The sample will show a total of 175 allocations and 175 deallocations, and no memory leaks.

However, if you uncomment out lines 126, and 127 in the main program, it will run both the standard lib and C++ allocation routines again, but not free the memory the second time through, and produce a detailed memory leak report in the memoryleak.txt file.

// Uncomment these next two lines
// if you want to see leaks in the memoryleak.txt file.
//AllocStdLibStyle(FALSE);
//AllocCPPStyle(FALSE);

Using the code

To use the code in your project add DebugMemory.cpp and DebugMemory.h to your project or makefile. Define DEBUG_MEMORY as a Preprocessor Definition for the compiler. Include DebugMemory.h in stdafx.h or in another .h file that gets included by all the code you want to debug. Add the routine DumpUnfreed(TRUE); to your code just before your program exits. Compile and test. 

// Add a call to DumpUnfreed(TRUE) at the end of your
// program to write the memoryleaks.txt file
// and find any leaks in your program.
//
// Passing TRUE to DumpUnfreed() will free the list
// of memory block breadcrumbs that the DebugMemory utility uses to
// keep track of the memory allocated by your program. 
// If you do not want to free the list, pass FALSE instead of TRUE.

DumpUnfreed(TRUE);
exit(0);

Points of Interest

The breadcrumb trail of memory blocks used by DebugMemory grows dynamically as needed by the utility, so you do not have to worry about setting some pre-defined size. The memory allocation for the list is not part of the DebugMemory trace.

Note that C++ objects that are singleton, have static or global scope, and allocate memory in their constructors, will show as leaking when you call DumpUnfreed() before you exit your program because their scalar destructors do not get called until the program is unloading as part of exit(0).

If you choose to use this code for a compiler other than Microsoft VC++, Developer Studio, or GCC 3.2.2, you may need to change the prototypes that use the preprocessors __cdecl, __FILE__ and __LINE__ to replacements suitable for your compiler. However, the code should port easily in other compiler environments since it does not require anything other than standard C runtime library elements.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here