How to Find the Source of Memory Leaks

When you run your (unmanaged/C++) application in debugger, you see at the end a report of memory leaks (if any are detected). Something like this:

Detected memory leaks!
Dumping objects ->
f:\dd\vctools\vc7libs\ship\atlmfc\src\mfc\strcore.cpp(141) : {381} normal block at 0x001FFC30, 54 bytes long.
Data: < x > 0C 00 B9 78 12 00 00 00 12 00 00 00 01 00 00 00
d:\marius\vc++\memoryleakstest\memoryleakstestdlg.cpp(163) : {380} normal block at 0x001FFBF0, 4 bytes long.
Data: <@ > 40 FC 1F 00
f:\dd\vctools\vc7libs\ship\atlmfc\src\mfc\thrdcore.cpp(306) : {374} client block at 0x001FFA38, subtype c0, 68 bytes long.
a CWinThread object at $001FFA38, 68 bytes long
Object dump complete.

Some of them can be fixed immediately, because when you double click on them Visual Studio will take you to the line where the allocation was made. Some of them are harder to spot, because Visual Studio is not able to do the same. Question is how do you find the source of those allocations? Luckily, there is this global variable called _crtBreakAlloc, that can be used to force the debugger to stop the execution when a certain block is allocated.

In order to use that, you should follow several steps:

  • First, you have to find a reproducible sequence that produces the same memory allocation number. When memory blocks are allocated, they are identified with a number, called allocation number. This number is reported by Visual Studio in brackets when it lists the memory leaks (e.g. {381}).
  • Second, you have to put a breakpoint somewhere in your program to force a stop at the beginning of the execution. That means you could use function main(), your CWinApp derived class constructor, function InitInstance() or other, depending on your application type and how early in the execution of the program the block that leaks is allocated. The smaller the allocation number is, the earlier in the execution the allocation occurs.
  • Run your program in debugger.
  • When the program stops (at the first breakpoint) open the Watch window and add the following expression: {,,msvcr90d.dll}_crtBreakAlloc in the Name column. In the Value column (which by default should have the value -1) write the allocation number. Take notice that msvcr90d.dll (which is the DLL that contains the C++ runtime library) is specific to Visual Studio 2008 (and is the debug version). If you use another version of Visual Studio, you have to use the appropriate DLL.
  • Continue debugging.
  • When the block identified by the allocation number set in the Watch window is allocated, the debugger will stop the execution and jump to a line from dbgheap.c.

    In order to see the line in your code that triggered the allocation, open the Call Stack window and find, from top down, the first function from your own code.

    That will lead you to the source of the memory leak.
If you are using Visual Studio 2015 or a newer version you need to use ucrtbased.dll instead of msvcrXXd.dll. This new DLL is part of the Universal C Runtime Library where the _crtBreakAlloc is available from.

See:

To read more about this topic see:

12 Replies to “How to Find the Source of Memory Leaks”

  1. I try to use the method you describe but when I add {,,msvcr90d.dll}_crtBreakAlloc in the name column, value become Module “msvcr90d.dll” not found. How can I add this module? Thank you

  2. I just found this blog post after hunting memory leak detectors. I’ve tried some, but they’re usually either expensive or destabilizing and crashing my app, for some reason.

    This sounds like an actual, working solution. After all, I _have_ good traces, it’s just that VS is satisfied with tracing it to strcore.cpp all the time, seemingly in 90% of our leaks. I’ll try it out right away! Thanks!

  3. I am trying to do this in Visual Studio 2017 and I don’t see a msvcr140d.dll?
    Do I use msvcp140.dll?

  4. My MFC app is heavily multithreaded and the allocation number for my leak is different every time. It would be nice if the error was clickable. Any de-leak suggestions using VS?

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.