A core feature of Visual Studio that allows developers to inspect, analyze, and troubleshoot code during execution.
Use the debug heap tools to identify which allocations weren’t freed and where they were made.
For MFC code:
- Take memory snapshots around the suspected code using
CMemoryState:#ifdef _DEBUG CMemoryState oldMemState, newMemState, diffMemState; oldMemState.Checkpoint(); { // Do your memory allocations and deallocations... CString s("This is a frame variable"); CPerson* p = new CPerson("Smith", "Alan", "581-0215"); // delete p; // if missing, this leaks } newMemState.Checkpoint(); if (diffMemState.Difference(oldMemState, newMemState)) { TRACE("Memory leaked!\n"); diffMemState.DumpAllObjectsSince(); } #endif - Run under the debugger and look at the Output window.
DumpAllObjectsSinceprints all blocks that weren’t freed. - The number in braces
{n}at the start of each line is the allocation sequence number. To break exactly when a leaked block is allocated, set_afxBreakAllocto that number before running again:
When the program hits that allocation, the debugger breaks and the call stack shows where the leak originates.#ifdef _DEBUG _afxBreakAlloc = 123; // allocation number from the dump #endif - For
CObject-derived classes, overrideDumpto get more useful information in the dump:class CPerson : public CObject { public: #ifdef _DEBUG virtual void Dump(CDumpContext& dc) const; #endif CString m_firstName; CString m_lastName; }; #ifdef _DEBUG void CPerson::Dump(CDumpContext& dc) const { CObject::Dump(dc); dc << "last name: " << m_lastName << "\n" << "first name: " << m_firstName << "\n"; } #endif - Place
Checkpointcalls outside the scope of local frame variables so their temporary heap allocations don’t clutter the leak report.
For general CRT-based C/C++ code:
- Enable the CRT debug heap in debug builds:
#define _CRTDBG_MAP_ALLOC #include <stdlib.h> #include <crtdbg.h> - At startup, enable automatic leak checking:
This causesint main() { _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF); // ... }_CrtDumpMemoryLeaksto run at process exit and print leaks to the Output window. - To get file/line information for
newallocations, wrapnewin a debug macro:
The leak report then shows the source file and line where the leaked allocation occurred.#ifdef _DEBUG #define DBG_NEW new(_NORMAL_BLOCK, __FILE__, __LINE__) #else #define DBG_NEW new #endif int* p = DBG_NEW int[10]; - Interpret the leak report:
- With
_CRTDBG_MAP_ALLOC, entries look like:c:\path\project\file.cpp(20) : {18} normal block at 0x00780E80, 64 bytes long. - Use the file and line to locate the offending allocation and ensure the corresponding
delete/freeis called.
- With
-
_CrtDumpMemoryLeaks()can also be called manually near program shutdown to dump leaks on demand. It returns nonzero if leaks are present.
Once the offending allocations are identified (via allocation number, file/line, or object dump), add the appropriate delete/free or fix ownership logic so those objects are released before program exit.
References: