Visual Leak Detector: Investigate Memory Leaks in Visual C++

Memory leaks are a part of life in C++. By default, Visual C++ looks for memory leaks when the program is executed in Debug mode. If any memory leaks are found when the program exits, it reports them in the Output window like this:

Detected memory leaks!
Dumping objects ->
{1372} normal block at 0x04BE1058, 136 bytes long.
Data: < 3-kt*-k        > 9C 33 2D 6B 74 2A 2D 6B C8 11 BE 04 00 00 00 00
Object dump complete.
The program '[408] Foobar.exe: Native' has exited with code 0 (0x0).

The leak information that it spits out is about memory blocks. The information that can be gleaned from this output is:

  • Memory block allocation number: 1372
  • Memory block type: normal
  • Memory block starting address: 0x04BE1058
  • Memory block size: 136 bytes
  • First 16 bytes of memory block data

This memory leak detection by Visual C++, which is always enabled in Debug mode, is very useful since it will always find a leak if it exists. Once the leak is known however, it is hard to figure out the source of the leak by examining the above information.

More probing along this line can be done using the definitions and calls from crtdbg.h. This is quite cumbersome and cannot always point out the source of the leak. Comprehensive information on this can be found in the MSDN article on Memory Leak Detection and Isolation.

Visual Leak Detector

Visual Leak Detector (VLD) is an open-source alternative to investigate these memory leaks. Using it is very simple and straightforward:

  • Download and install VLD. The installer will prompt about adding its bin path (C:\...\Visual Leak Detector\bin) to the PATH environment variable. Accept it or add it manually yourself. Either way, you will need to log out and log back in for the addition to the PATH to take effect. vld.dll and dbghelp.dll, from the bin directory need to be available on the system path.
  • Make sure the Visual C++ project is in Debug mode.
  • Add the VLD include path (C:\...\Visual Leak Detector\include) to the Include Directories of the project.
  • Add the VLD lib path (C:\...\Visual Leak Detector\lib) to the Additional Library Directories of the project.
  • Add #include <vld.h> to any of the C++ source files in the project. This header will bring in vld.lib during the linking stage.
  • Rebuild the project and execute the compiled program in Debug mode. On program exit, VLD will print out the memory leak information it detected in the Output window.

The memory leak information printed by VLD looks like this:

---------- Block 1199 at 0x04BE1058: 136 bytes ----------
Call Stack:
d:\Foobar\FooLog.cpp (26): FooLog::getInstance
d:\Foobar\FooMain.cpp (75): FooMain::init
f:\dd\vctools\crt_bld\self_x86\crt\src\crtexe.c (578): __tmainCRTStartup
f:\dd\vctools\crt_bld\self_x86\crt\src\crtexe.c (403): WinMainCRTStartup
0x759A3677 (File and line number not available): BaseThreadInitThunk
0x770C9D42 (File and line number not available): RtlInitializeExceptionChain
0x770C9D15 (File and line number not available): RtlInitializeExceptionChain
9C 33 2D 6B    74 2A 2D 6B    C8 11 BE 04    00 00 00 00     .3-kt*-k ........
00 00 00 00    70 14 BB 6C    70 14 BB 6C    00 00 00 00     ....p..l p..l....
00 00 00 00    68 14 BB 6C    68 14 BB 6C    00 00 00 00     ....h..l h..l....
00 00 00 00    6C 14 BB 6C    6C 14 BB 6C    20 12 BE 04     ....l..l l..l....
00 00 00 00    CD 00 CD CD    00 00 00 00    01 CD CD CD     ........ ........
68 14 BB 6C    78 33 2D 6B    00 00 00 00    00 00 00 00     h..lx3-k ........
00 00 00 00    01 02 00 00    06 00 00 00    00 00 00 00     ........ ........
00 00 00 00    00 00 00 00    88 11 BE 04    5C 10 BE 04     ........ ....\...
00 00 00 00    20 CD CD CD                                   ........ ........

We can note the following information from this output:

  • The block allocation number output by Visual C++ leak detection and by VLD do not necessarily match.
  • The memory block address and size information of Visual C++ and VLD match. This confirms that this VLD information is about the same memory block as that reported by Visual C++. This is useful when the program has multiple memory leaks. The programmer can then match each of the Visual C++ memory leak to the corresponding VLD memory leak information.
  • VLD provides a lot of information: the entire call stack trace with function call names, source code filenames and line numbers. It also prints out a lot more data from the memory block.

By looking at the sourecode filename and the line number in it, the programmer should be able to get solid leads to the memory leak and hopefully be able to fix it. 🙂