[c++] How to find memory leak in a C++ code/project?

I am a C++ programmer on the Windows platform. I am using Visual Studio 2008.

I usually end up in the code with memory leaks.

Normally I find the memory leak by inspecting the code, but it is cumbersome and is not always a good approach.

Since I can't afford a paid memory leak detection tool, I wanted you guys to suggest the best possible ways to avoid memory leaks.

  1. I want to the know how the programmer can find memory leaks.
  2. Is there any standard or procedure one should follow to ensure there is no memory leak in the program?

This question is related to c++ memory-leaks

The answer is


Make certain that all the heap memory is successfully freed. There is no need if you never allocate memory on the heap. If you do, count the number of times you malloc memory, and count up the number of time you free memory.


You can use the tool Valgrind to detect memory leaks.

Also, to find the leak in a particular function, use exit(0) at the end of the function and then run it with Valgrind

`$` valgrind ./your_CPP_program 

If you use gcc, there's gprof available.

I wanted to the know how programmer find memory leak

Some uses tools, some does what you do, could also through peer code review

Is there any standard or procedure one should follow to ensure there is no memory leak in the program

For me: whenever I create dynamically allocated objects, I always put the freeing code after, then fill the code between. This would be OK if you're sure there won't be exceptions in the code between. Otherwise, I make use of try-finally (I don't use C++ frequently).


Visual Leak Detector (VLD) is a free, robust, open-source memory leak detection system for Visual C++.

When you run your program under the Visual Studio debugger, Visual Leak Detector will output a memory leak report at the end of your debugging session. The leak report includes the full call stack showing how any leaked memory blocks were allocated. Double-click on a line in the call stack to jump to that file and line in the editor window.

If you only have crash dumps, you can use the Windbg !heap -l command, it will detect leaked heap blocks. Better open the gflags option: “Create user mode stack trace database”, then you will see the memory allocation call stack.


Neither "new" or "delete" should ever be used in application code. Instead, create a new type that uses the manager/worker idiom, in which the manager class allocates and frees memory and forwards all other operations to the worker object.

Unfortunately this is more work than it should be because C++ doesn't have overloading of "operator .". It is even more work in the presence of polymorphism.

But this is worth the effort because you then don't ever have to worry about memory leaks, which means you don't even have to look for them.


  1. Download Debugging Tools for Windows.
  2. Use the gflags utility to turn on user-mode stack traces.
  3. Use UMDH to take multiple snapshots of your program's memory. Take a snapshot before memory gets allocated, and take a second snapshot after a point at which you believe that your program has leaked memory. You might want to add pauses or prompts in your program to give you a chance to run UMDH and take the snapshots.
  4. Run UMDH again, this time in its mode that does a diff between the two snapshots. It will then generate a report containing the call stacks of suspected memory leaks.
  5. Restore your previous gflags settings when you're done.

UMDH will give you more information than the CRT debug heap because it is watching memory allocations across your entire process; it can even tell you if third-party components are leaking.


  1. In visual studio, there is a built in detector for memory leak called C Runtime Library. When your program exits after the main function returns, CRT will check the debug heap of your application. if you have any blocks still allocated on the debug heap, then you have memory leak..

  2. This forum discusses a few ways to avoid memory leakage in C/C++..


On Windows you can use CRT debug heap.

Is there any standard or procedure one should follow to ensure there is no memory leak in the program.

Yeah, don't use manual memory management (if you ever call delete or delete[] manually, then you're doing it wrong). Use RAII and smart pointers, limit heap allocations to the absolute minimum (most of the time, automatic variables will suffice).


There are some well-known programming techniques that will help you to minimize the risk of getting memory leaks at first hand:

  • if you have to do your own dynamic memory allocation, write new and delete always pairwise, and make sure the allocation/deallocation code is called pairwise
  • avoid dynamic memory allocation if you can. For example, use vector<T> t whereever possible instead of T* t = new T[size]
  • use "smart pointers" like boost smart pointers (http://www.boost.org/doc/libs/1_46_1/libs/smart_ptr/smart_ptr.htm)
  • my personal favorite: make sure you have understood the concept of ownership of a pointer, and make sure that everywhere where you use pointers, you know which code entity is the owner
  • learn which constructors / assignment operators are automatically created by the C++ compiler, and what that means if you have class that owns a pointer (or what that means if you have a class that contains a pointer to an object it does not own).

Answering the second part of your question,

Is there any standard or procedure one should follow to ensure there is no memory leak in the program.

Yes, there is. And this is one of the key differences between C and C++.

In C++, you should never call new or delete in your user code. RAII is a very commonly used technique, which pretty much solves the resource management problem. Every resource in your program (a resource is anything that has to be acquired, and then later on, released: file handles, network sockets, database connections, but also plain memory allocations, and in some cases, pairs of API calls (BeginX()/EndX(), LockY(), UnlockY()), should be wrapped in a class, where:

  • the constructor acquires the resource (by calling new if the resource is a memroy allocation)
  • the destructor releases the resource,
  • copying and assignment is either prevented (by making the copy constructor and assignment operators private), or are implemented to work correctly (for example by cloning the underlying resource)

This class is then instantiated locally, on the stack, or as a class member, and not by calling new and storing a pointer.

You often don't need to define these classes yourself. The standard library containers behave in this way as well, so that any object stored into a std::vector gets freed when the vector is destroyed. So again, don't store a pointer into the container (which would require you to call new and delete), but rather the object itself (which gives you memory management for free). Likewise, smart pointer classes can be used to easily wrap objects that just have to be allocated with new, and control their lifetimes.

This means that when the object goes out of scope, it is automatically destroyed, and its resource released and cleaned up.

If you do this consistently throughout your code, you simply won't have any memory leaks. Everything that could get leaked is tied to a destructor which is guaranteed to be called when control leaves the scope in which the object was declared.



Running "Valgrind" can:

1) Help Identify Memory Leaks - show you how many memory leaks you have, and point out to the lines in the code where the leaked memory was allocated.

2) Point out wrong attempts to free memory (e.g. improper call of delete)

Instructions for using "Valgrind"

1) Get valgrind here.

2) Compile your code with -g flag

3) In your shell run:

valgrind --leak-check=yes myprog arg1 arg2

Where "myprog" is your compiled program and arg1, arg2 your programme's arguments.

4) The result is a list of calls to malloc/new that did not have subsequent calls to free delete.

For example:

==4230==    at 0x1B977DD0: malloc (vg_replace_malloc.c:136)

==4230==    by 0x804990F: main (example.c:6)

Tells you in which line the malloc (that was not freed) was called.

As Pointed out by others, make sure that for every new/malloc call, you have a subsequent delete/free call.


AddressSanitizer (ASan) is a fast memory error detector. It finds use-after-free and {heap,stack,global}-buffer overflow bugs in C/C++ programs. It finds:

  • Use after free (dangling pointer dereference)
  • Heap buffer overflow
  • Stack buffer overflow
  • Global buffer overflow
  • Use after return
  • Initialization order bugs

This tool is very fast. The average slowdown of the instrumented program is ~2x.


You can use some techniques in your code to detect memory leak. The most common and most easy way to detect is, define a macro say, DEBUG_NEW and use it, along with predefined macros like __FILE__ and __LINE__ to locate the memory leak in your code. These predefined macros tell you the file and line number of memory leaks.

DEBUG_NEW is just a MACRO which is usually defined as:

#define DEBUG_NEW new(__FILE__, __LINE__)
#define new DEBUG_NEW

So that wherever you use new, it also can keep track of the file and line number which could be used to locate memory leak in your program.

And __FILE__, __LINE__ are predefined macros which evaluate to the filename and line number respectively where you use them!

Read the following article which explains the technique of using DEBUG_NEW with other interesting macros, very beautifully:

A Cross-Platform Memory Leak Detector


From Wikpedia,

Debug_new refers to a technique in C++ to overload and/or redefine operator new and operator delete in order to intercept the memory allocation and deallocation calls, and thus debug a program for memory usage. It often involves defining a macro named DEBUG_NEW, and makes new become something like new(_FILE_, _LINE_) to record the file/line information on allocation. Microsoft Visual C++ uses this technique in its Microsoft Foundation Classes. There are some ways to extend this method to avoid using macro redefinition while still able to display the file/line information on some platforms. There are many inherent limitations to this method. It applies only to C++, and cannot catch memory leaks by C functions like malloc. However, it can be very simple to use and also very fast, when compared to some more complete memory debugger solutions.


In addition to the tools and methodes provided in the other anwers, static code analysis tools can be used to detect memory leaks (and other issues as well). A free an robust tool is Cppcheck. But there are a lot of other tools available. Wikipedia has a list of static code analysis tools.


MTuner is a free multi platform memory profiling, leak detection and analysis tool supporting MSVC, GCC and Clang compilers. Features include:

  • timeline based history of memory usage and live memory blocks
  • powerful memory operation filtering based on heap, memory tag, time range, etc.
  • SDK for manual instrumentation with full source code
  • continuous integration support through command line usage
  • call stack tree and tree map navigation
  • much more.

Users can profile any software targeting platforms with GCC or Clang cross compilers. MTuner comes with built in support for Windows, PlayStation 4 and PlayStation 3 platforms.


Search your code for occurrences of new, and make sure that they all occur within a constructor with a matching delete in a destructor. Make sure that this is the only possibly throwing operation in that constructor. A simple way to do this is to wrap all pointers in std::auto_ptr, or boost::scoped_ptr (depending on whether or not you need move semantics). For all future code just ensure that every resource is owned by an object that cleans up the resource in its destructor. If you need move semantics then you can upgrade to a compiler that supports r-value references (VS2010 does I believe) and create move constructors. If you don't want to do that then you can use a variety of tricky techniques involving conscientious usage of swap, or try the Boost.Move library.


A survey of automatic memory leak checkers

In this answer, I compare several different memory leak checkers in a simple easy to understand memory leak example.

Before anything, see this huge table in the ASan wiki which compares all tools known to man: https://github.com/google/sanitizers/wiki/AddressSanitizerComparisonOfMemoryTools/d06210f759fec97066888e5f27c7e722832b0924

The example analyzed will be:

main.c

#include <stdlib.h>

void * my_malloc(size_t n) {
    return malloc(n);
}

void leaky(size_t n, int do_leak) {
    void *p = my_malloc(n);
    if (!do_leak) {
        free(p);
    }
}

int main(void) {
    leaky(0x10, 0);
    leaky(0x10, 1);
    leaky(0x100, 0);
    leaky(0x100, 1);
    leaky(0x1000, 0);
    leaky(0x1000, 1);
}

GitHub upstream.

We will try to see how clearly do the different tools point us to the leaky calls.

tcmalloc from gperftools by Google

https://github.com/gperftools/gperftools

Usage on Ubuntu 19.04:

sudo apt-get install google-perftools
gcc -ggdb3 -o main.out main.c -ltcmalloc
PPROF_PATH=/usr/bin/google-pprof \
  HEAPCHECK=normal \
  HEAPPROFILE=ble \
  ./main.out \
;
google-pprof main.out ble.0001.heap --text

The output of the program run contains the memory leak analysis:

WARNING: Perftools heap leak checker is active -- Performance may suffer
Starting tracking the heap
Dumping heap profile to ble.0001.heap (Exiting, 4 kB in use)
Have memory regions w/o callers: might report false leaks
Leak check _main_ detected leaks of 272 bytes in 2 objects
The 2 largest leaks:
Using local file ./main.out.
Leak of 256 bytes in 1 objects allocated from:
        @ 555bf6e5815d my_malloc
        @ 555bf6e5817a leaky
        @ 555bf6e581d3 main
        @ 7f71e88c9b6b __libc_start_main
        @ 555bf6e5808a _start
Leak of 16 bytes in 1 objects allocated from:
        @ 555bf6e5815d my_malloc
        @ 555bf6e5817a leaky
        @ 555bf6e581b5 main
        @ 7f71e88c9b6b __libc_start_main
        @ 555bf6e5808a _start


If the preceding stack traces are not enough to find the leaks, try running THIS shell command:

pprof ./main.out "/tmp/main.out.24744._main_-end.heap" --inuse_objects --lines --heapcheck  --edgefraction=1e-10 --nodefraction=1e-10 --gv

If you are still puzzled about why the leaks are there, try rerunning this program with HEAP_CHECK_TEST_POINTER_ALIGNMENT=1 and/or with HEAP_CHECK_MAX_POINTER_OFFSET=-1
If the leak report occurs in a small fraction of runs, try running with TCMALLOC_MAX_FREE_QUEUE_SIZE of few hundred MB or with TCMALLOC_RECLAIM_MEMORY=false, it might help find leaks more re
Exiting with error code (instead of crashing) because of whole-program memory leaks

and the output of google-pprof contains the heap usage analysis:

Using local file main.out.
Using local file ble.0001.heap.
Total: 0.0 MB
     0.0 100.0% 100.0%      0.0 100.0% my_malloc
     0.0   0.0% 100.0%      0.0 100.0% __libc_start_main
     0.0   0.0% 100.0%      0.0 100.0% _start
     0.0   0.0% 100.0%      0.0 100.0% leaky
     0.0   0.0% 100.0%      0.0 100.0% main

The output points us to two of the three leaks:

Leak of 256 bytes in 1 objects allocated from:
        @ 555bf6e5815d my_malloc
        @ 555bf6e5817a leaky
        @ 555bf6e581d3 main
        @ 7f71e88c9b6b __libc_start_main
        @ 555bf6e5808a _start
Leak of 16 bytes in 1 objects allocated from:
        @ 555bf6e5815d my_malloc
        @ 555bf6e5817a leaky
        @ 555bf6e581b5 main
        @ 7f71e88c9b6b __libc_start_main
        @ 555bf6e5808a _start

I'm not sure why the third one didn't show up

In any case, when usually when something leaks, it happens a lot of times, and when I used it on a real project, I just ended up being pointed out to the leaking function very easily.

As mentioned on the output itself, this incurs a significant execution slowdown.

Further documentation at:

See also: How To Use TCMalloc?

Tested in Ubuntu 19.04, google-perftools 2.5-2.

Address Sanitizer (ASan) also by Google

https://github.com/google/sanitizers

Previously mentioned at: How to find memory leak in a C++ code/project? TODO vs tcmalloc.

This is already integrated into GCC, so you can just do:

gcc -fsanitize=address -ggdb3 -o main.out main.c
./main.out 

and execution outputs:

=================================================================
==27223==ERROR: LeakSanitizer: detected memory leaks

Direct leak of 4096 byte(s) in 1 object(s) allocated from:
    #0 0x7fabbefc5448 in malloc (/usr/lib/x86_64-linux-gnu/libasan.so.5+0x10c448)
    #1 0x55bf86c5f17c in my_malloc /home/ciro/test/main.c:4
    #2 0x55bf86c5f199 in leaky /home/ciro/test/main.c:8
    #3 0x55bf86c5f210 in main /home/ciro/test/main.c:20
    #4 0x7fabbecf4b6a in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x26b6a)

Direct leak of 256 byte(s) in 1 object(s) allocated from:
    #0 0x7fabbefc5448 in malloc (/usr/lib/x86_64-linux-gnu/libasan.so.5+0x10c448)
    #1 0x55bf86c5f17c in my_malloc /home/ciro/test/main.c:4
    #2 0x55bf86c5f199 in leaky /home/ciro/test/main.c:8
    #3 0x55bf86c5f1f2 in main /home/ciro/test/main.c:18
    #4 0x7fabbecf4b6a in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x26b6a)

Direct leak of 16 byte(s) in 1 object(s) allocated from:
    #0 0x7fabbefc5448 in malloc (/usr/lib/x86_64-linux-gnu/libasan.so.5+0x10c448)
    #1 0x55bf86c5f17c in my_malloc /home/ciro/test/main.c:4
    #2 0x55bf86c5f199 in leaky /home/ciro/test/main.c:8
    #3 0x55bf86c5f1d4 in main /home/ciro/test/main.c:16
    #4 0x7fabbecf4b6a in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x26b6a)

SUMMARY: AddressSanitizer: 4368 byte(s) leaked in 3 allocation(s).

which clearly identifies all leaks. Nice!

ASan can also do other cool checks such as out-of-bounds writes: Stack smashing detected

Tested in Ubuntu 19.04, GCC 8.3.0.

Valgrind

http://www.valgrind.org/

Previously mentioned at: https://stackoverflow.com/a/37661630/895245

Usage:

sudo apt-get install valgrind
gcc -ggdb3 -o main.out main.c
valgrind --leak-check=yes ./main.out

Output:

==32178== Memcheck, a memory error detector
==32178== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==32178== Using Valgrind-3.14.0 and LibVEX; rerun with -h for copyright info
==32178== Command: ./main.out
==32178== 
==32178== 
==32178== HEAP SUMMARY:
==32178==     in use at exit: 4,368 bytes in 3 blocks
==32178==   total heap usage: 6 allocs, 3 frees, 8,736 bytes allocated
==32178== 
==32178== 16 bytes in 1 blocks are definitely lost in loss record 1 of 3
==32178==    at 0x483874F: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==32178==    by 0x10915C: my_malloc (main.c:4)
==32178==    by 0x109179: leaky (main.c:8)
==32178==    by 0x1091B4: main (main.c:16)
==32178== 
==32178== 256 bytes in 1 blocks are definitely lost in loss record 2 of 3
==32178==    at 0x483874F: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==32178==    by 0x10915C: my_malloc (main.c:4)
==32178==    by 0x109179: leaky (main.c:8)
==32178==    by 0x1091D2: main (main.c:18)
==32178== 
==32178== 4,096 bytes in 1 blocks are definitely lost in loss record 3 of 3
==32178==    at 0x483874F: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==32178==    by 0x10915C: my_malloc (main.c:4)
==32178==    by 0x109179: leaky (main.c:8)
==32178==    by 0x1091F0: main (main.c:20)
==32178== 
==32178== LEAK SUMMARY:
==32178==    definitely lost: 4,368 bytes in 3 blocks
==32178==    indirectly lost: 0 bytes in 0 blocks
==32178==      possibly lost: 0 bytes in 0 blocks
==32178==    still reachable: 0 bytes in 0 blocks
==32178==         suppressed: 0 bytes in 0 blocks
==32178== 
==32178== For counts of detected and suppressed errors, rerun with: -v
==32178== ERROR SUMMARY: 3 errors from 3 contexts (suppressed: 0 from 0)

So once again, all leaks were detected.

See also: How do I use valgrind to find memory leaks?

Tested in Ubuntu 19.04, valgrind 3.14.0.