The primary tools for detecting memory leaks are the C/C debugger and the C Run-time Library (CRT) debug heap functions. Nuendo 4 all vst plugins free download. To enable all the debug heap functions, include the following statements in your C program, in the following order: #define CRTDBGMAPALLOC #include #include The #define statement maps a base.
-->Memory leaks are among the most subtle and hard-to-detect bugs in C/C++ apps. Memory leaks result from the failure to correctly deallocate memory that was previously allocated. A small memory leak might not be noticed at first, but over time can cause symptoms ranging from poor performance to crashing when the app runs out of memory. A leaking app that uses up all available memory can cause other apps to crash, creating confusion as to which app is responsible. Even harmless memory leaks might indicate other problems that should be corrected.
The Visual Studio debugger and C Run-time Library (CRT) can help you detect and identify memory leaks.
Enable memory leak detection
The primary tools for detecting memory leaks are the C/C++ debugger and the C Run-time Library (CRT) debug heap functions.
To enable all the debug heap functions, include the following statements in your C++ program, in the following order:
The
#define
statement maps a base version of the CRT heap functions to the corresponding debug version. If you leave out the #define
statement, the memory leak dump will be less detailed.Including crtdbg.h maps the
malloc
and free
functions to their debug versions, _malloc_dbg and _free_dbg, which track memory allocation and deallocation. This mapping occurs only in debug builds, which have _DEBUG
. Release builds use the ordinary malloc
and free
functions.After you've enabled the debug heap functions by using the preceding statements, place a call to _CrtDumpMemoryLeaks before an app exit point to display a memory-leak report when the app exits.
If your app has several exits, you don't need to manually place
_CrtDumpMemoryLeaks
at every exit point. To cause an automatic call to _CrtDumpMemoryLeaks
at each exit point, place a call to _CrtSetDbgFlag
at the beginning of your app with the bit fields shown here:By default,
_CrtDumpMemoryLeaks
outputs the memory-leak report to the Debug pane of the Output window. If you use a library, the library might reset the output to another location.You can use
_CrtSetReportMode
to redirect the report to another location, or back to the Output window as shown here:Interpret the memory-leak report
If your app doesn't define
_CRTDBG_MAP_ALLOC
, _CrtDumpMemoryLeaks displays a memory-leak report that looks like:If your app defines
_CRTDBG_MAP_ALLOC
, the memory-leak report looks like:The second report shows the filename and line number where the leaked memory is first allocated.
Whether or not you define
_CRTDBG_MAP_ALLOC
, the memory-leak report displays:- The memory allocation number, which is
18
in the example - The block type,
normal
in the example. - The hexadecimal memory location,
0x00780E80
in the example. - The size of the block,
64 bytes
in the example. - The first 16 bytes of data in the block, in hexadecimal form.
Memory block types are normal, client, or CRT. A normal block is ordinary memory allocated by your program. A client block is a special type of memory block used by MFC programs for objects that require a destructor. The MFC
new
operator creates either a normal block or a client block, as appropriate for the object being created.A CRT block is allocated by the CRT library for its own use. The CRT library handles the deallocation for these blocks, so CRT blocks won't appear in the memory-leak report unless there are serious problems with the CRT library.
There are two other types of memory blocks that never appear in memory-leak reports. A free block is memory that has been released, so by definition isn't leaked. An ignore block is memory that you've explicitly marked to exclude from the memory-leak report.
The preceding techniques identify memory leaks for memory allocated using the standard CRT
malloc
function. If your program allocates memory using the C++ new
operator, however, you may only see the filename and line number where operator new
calls _malloc_dbg
in the memory-leak report. To create a more useful memory-leak report, you can write a macro like the following to report the line that made the allocation:Now you can replace the
new
operator by using the DBG_NEW
macro in your code. In debug builds, DBG_NEW
uses an overload of global operator new
that takes additional parameters for the block type, file, and line number. The overload of new
calls _malloc_dbg
to record the extra information. The memory-leak reports show the filename and line number where the leaked objects were allocated. Release builds still use the default new
. Here's an example of the technique:When you run this code in the Visual Studio debugger, the call to
_CrtDumpMemoryLeaks
generates a report in the Output window that looks similar to:This output reports that the leaked allocation was on line 20 of debug_new.cpp.
Note
We don't recommend you create a preprocessor macro named
new
, or any other language keyword.Set breakpoints on a memory allocation number
The memory allocation number tells you when a leaked memory block was allocated. A block with a memory allocation number of 18, for example, is the 18th block of memory allocated during the run of the app. The CRT report counts all memory-block allocations during the run, including allocations by the CRT library and other libraries such as MFC. Therefore, memory allocation block number 18 probably isn't the 18th memory block allocated by your code.
You can use the allocation number to set a breakpoint on the memory allocation.
To set a memory-allocation breakpoint using the Watch window:
- Set a breakpoint near the start of your app, and start debugging.
- When the app pauses at the breakpoint, open a Watch window by selecting Debug > Windows > Watch 1 (or Watch 2, Watch 3, or Watch 4).
- In the Watch window, type
_crtBreakAlloc
in the Name column.If you're using the multithreaded DLL version of the CRT library (the /MD option), add the context operator:{,ucrtbased.dll}_crtBreakAlloc
Make sure that debug symbols are loaded. Otherwise_crtBreakAlloc
will be reported as unidentified. - Press Enter.The debugger evaluates the call and places the result in the Value column. This value will be -1 if you have not set any breakpoints on memory allocations.
- In the Value column, replace the value with the allocation number of the memory allocation where you want the debugger to break.
After you set a breakpoint on a memory-allocation number, continue to debug. Make sure to run under the same conditions, so the memory-allocation number doesn't change. When your program breaks at the specified memory allocation, use the Call Stack window and other debugger windows to determine the conditions under which the memory was allocated. Then, you can continue execution to observe what happens to the object and determine why it isn't correctly deallocated.
Setting a data breakpoint on the object might also be helpful. For more information, see Using breakpoints.
You can also set memory-allocation breakpoints in code. You can set:
or:
Compare memory states
Another technique for locating memory leaks involves taking snapshots of the application's memory state at key points. To take a snapshot of the memory state at a given point in your application, create a
_CrtMemState
structure and pass it to the _CrtMemCheckpoint
function.The
_CrtMemCheckpoint
function fills in the structure with a snapshot of the current memory state.To output the contents of a
_CrtMemState
structure, pass the structure to the _ CrtMemDumpStatistics
function:_ CrtMemDumpStatistics
outputs a dump of memory state that looks like:To determine whether a memory leak has occurred in a section of code, you can take snapshots of the memory state before and after the section, and then use
_ CrtMemDifference
to compare the two states:_CrtMemDifference
compares the memory states s1
and s2
and returns a result in (s3
) that is the difference between s1
and s2
.One technique for finding memory leaks begins by placing
_CrtMemCheckpoint
calls at the beginning and end of your app, then using _CrtMemDifference
to compare the results. If _CrtMemDifference
shows a memory leak, you can add more _CrtMemCheckpoint
calls to divide your program using a binary search, until you've isolated the source of the leak.False positives
_CrtDumpMemoryLeaks
can give false indications of memory leaks if a library marks internal allocations as normal blocks instead of CRT blocks or client blocks. In that case, _CrtDumpMemoryLeaks
is unable to tell the difference between user allocations and internal library allocations. If the global destructors for the library allocations run after the point where you call _CrtDumpMemoryLeaks
, every internal library allocation is reported as a memory leak. Versions of the Standard Template Library earlier than Visual Studio .NET may cause _CrtDumpMemoryLeaks
to report such false positives.See also
-->This topic provides a detailed look at the CRT debug heap.
Contents
Find buffer overruns with debug heap
Two of the most common and intractable problems that programmers encounter are overwriting the end of an allocated buffer and memory leaks (failing to free allocations after they are no longer needed). The debug heap provides powerful tools to solve memory allocation problems of this kind.
The Debug versions of the heap functions call the standard or base versions used in Release builds. When you request a memory block, the debug heap manager allocates from the base heap a slightly larger block of memory than requested and returns a pointer to your portion of that block. For example, suppose your application contains the call:
malloc( 10 )
. In a Release build, malloc would call the base heap allocation routine requesting an allocation of 10 bytes. In a Debug build, however, malloc
would call _malloc_dbg, which would then call the base heap allocation routine requesting an allocation of 10 bytes plus approximately 36 bytes of additional memory. All the resulting memory blocks in the debug heap are connected in a single linked list, ordered according to when they were allocated.The additional memory allocated by the debug heap routines is used for bookkeeping information, for pointers that link debug memory blocks together, and for small buffers on either side of your data to catch overwrites of the allocated region.
Currently, the block header structure used to store the debug heap's bookkeeping information is declared as follows in the DBGINT.H header file:
The
NoMansLand
buffers on either side of the user data area of the block are currently 4 bytes in size, and are filled with a known byte value used by the debug heap routines to verify that the limits of the user's memory block have not been overwritten. The debug heap also fills new memory blocks with a known value. If you elect to keep freed blocks in the heap's linked list as explained below, these freed blocks are also filled with a known value. Currently, the actual byte values used are as follows:NoMansLand (0xFD)The 'NoMansLand' buffers on either side of the memory used by an application are currently filled with 0xFD.
Freed blocks (0xDD)The freed blocks kept unused in the debug heap's linked list when the
_CRTDBG_DELAY_FREE_MEM_DF
flag is set are currently filled with 0xDD.New objects (0xCD)New objects are filled with 0xCD when they are allocated.
Types of blocks on the debug heap
Every memory block in the debug heap is assigned to one of five allocation types. These types are tracked and reported differently for purposes of leak detection and state reporting. You can specify a block's type by allocating it using a direct call to one of the debug heap allocation functions such as _malloc_dbg. The five types of memory blocks in the debug heap (set in the nBlockUse member of the _CrtMemBlockHeader structure) are as follows:
_NORMAL_BLOCKA call to malloc or calloc creates a Normal block. If you intend to use Normal blocks only, and have no need for Client blocks, you may want to define _CRTDBG_MAP_ALLOC, which causes all heap allocation calls to be mapped to their debug equivalents in Debug builds. This will allow file name and line number information about each allocation call to be stored in the corresponding block header.
_CRT_BLOCK
The memory blocks allocated internally by many run-time library functions are marked as CRT blocks so they can be handled separately. As a result, leak detection and other operations need not be affected by them. An allocation must never allocate, reallocate, or free any block of CRT type._CLIENT_BLOCK
An application can keep special track of a given group of allocations for debugging purposes by allocating them as this type of memory block, using explicit calls to the debug heap functions. MFC, for example, allocates all CObjects as Client blocks; other applications might keep different memory objects in Client blocks. Subtypes of Client blocks can also be specified for greater tracking granularity. To specify subtypes of Client blocks, shift the number left by 16 bits and OR
it with _CLIENT_BLOCK
. For example:A client-supplied hook function for dumping the objects stored in Client blocks can be installed using _CrtSetDumpClient, and will then be called whenever a Client block is dumped by a debug function. Also, _CrtDoForAllClientObjects can be used to call a given function supplied by the application for every Client block in the debug heap.
_FREE_BLOCKNormally, blocks that are freed are removed from the list. To check that freed memory is not still being written to or to simulate low memory conditions, you can choose to keep freed blocks on the linked list, marked as Free and filled with a known byte value (currently 0xDD).
_IGNORE_BLOCKIt is possible to turn off the debug heap operations for a period of time. During this time, memory blocks are kept on the list, but are marked as Ignore blocks.
To determine the type and subtype of a given block, use the function _CrtReportBlockType and the macros _BLOCK_TYPE and _BLOCK_SUBTYPE. The macros are defined (in crtdbg.h), as follows:
Check for heap integrity and memory leaks
Many of the debug heap's features must be accessed from within your code. The following section describes some of the features and how to use them.
_CrtCheckMemory
You can use a call to _CrtCheckMemory, for example, to check the heap's integrity at any point. This function inspects every memory block in the heap, verifies that the memory block header information is valid, and confirms that the buffers have not been modified._CrtSetDbgFlag
You can control how the debug heap keeps track of allocations using an internal flag, _crtDbgFlag, which can be read and set using the _CrtSetDbgFlag function. By changing this flag, you can instruct the debug heap to check for memory leaks when the program exits and report any leaks that are detected. Similarly, you can specify that freed memory blocks not be removed from the linked list, to simulate low-memory situations. When the heap is checked, these freed blocks are inspected in their entirety to ensure that they have not been disturbed.The _crtDbgFlag flag contains the following bit fields:
Bit field | Default value | Description |
---|---|---|
_CRTDBG_ALLOC_MEM_DF | On | Turns on debug allocation. When this bit is off, allocations remain chained together but their block type is _IGNORE_BLOCK. |
_CRTDBG_DELAY_FREE_MEM_DF | Off | Prevents memory from actually being freed, as for simulating low-memory conditions. When this bit is on, freed blocks are kept in the debug heap's linked list but are marked as _FREE_BLOCK and filled with a special byte value. |
_CRTDBG_CHECK_ALWAYS_DF | Off | Causes _CrtCheckMemory to be called at every allocation and deallocation. This slows execution, but catches errors quickly. |
_CRTDBG_CHECK_CRT_DF | Off | Causes blocks marked as type _CRT_BLOCK to be included in leak-detection and state-difference operations. When this bit is off, the memory used internally by the run-time library is ignored during such operations. |
_CRTDBG_LEAK_CHECK_DF | Off | Causes leak checking to be performed at program exit via a call to _CrtDumpMemoryLeaks. An error report is generated if the application has failed to free all the memory that it allocated. |
Configure the debug heap
All calls to heap functions such as
malloc
, free
, calloc
, realloc
, new
, and delete
resolve to debug versions of those functions that operate in the debug heap. When you free a memory block, the debug heap automatically checks the integrity of the buffers on either side of your allocated area and issues an error report if overwriting has occurred.To use the debug heap
- Link the debug build of your application with a debug version of the C run-time library. Kickstart vst free download.To change one or more _crtDbgFlag bit fields and create a new state for the flag
- Call
_CrtSetDbgFlag
with thenewFlag
parameter set to_CRTDBG_REPORT_FLAG
(to obtain the current_crtDbgFlag
state) and store the returned value in a temporary variable. - Turn on any bits by
OR
-ing (bitwise | symbol) the temporary variable with the corresponding bitmasks (represented in the application code by manifest constants). - Turn off the other bits by
AND
-ing (bitwise & symbol) the variable with aNOT
(bitwise ~ symbol) of the appropriate bitmasks. - Call
_CrtSetDbgFlag
with thenewFlag
parameter set to the value stored in the temporary variable to create the new state for_crtDbgFlag
.For example, the following lines of code turn on automatic leak detection and turn off checking for blocks of type_CRT_BLOCK
:
new, delete, and _CLIENT_BLOCKs in the C++ debug heap
The debug versions of the C run-time library contain debug versions of the C++
new
and delete
operators. If you use the _CLIENT_BLOCK
allocation type, you must call the debug version of the new
operator directly or create macros that replace the new
operator in debug mode, as shown in the following example:The Debug version of the
delete
operator works with all block types and requires no changes in your program when you compile a Release version.Heap State Reporting Functions
_CrtMemState
To capture a summary snapshot of the state of the heap at a given time, use the _CrtMemState structure defined in CRTDBG.H:
This structure saves a pointer to the first (most recently allocated) block in the debug heap's linked list. Then, in two arrays, it records how many of each type of memory block (_NORMAL_BLOCK,
_CLIENT_BLOCK
, _FREE_BLOCK, and so on) are in the list and the number of bytes allocated in each type of block. Finally, it records the highest number of bytes allocated in the heap as a whole up to that point, and the number of bytes currently allocated.Other CRT Reporting Functions
The following functions report the state and contents of the heap, and use the information to help detect memory leaks and other problems.
Function | Description |
---|---|
_CrtMemCheckpoint | Saves a snapshot of the heap in a _CrtMemState structure supplied by the application. |
_CrtMemDifference | Compares two memory state structures, saves the difference between them in a third state structure, and returns TRUE if the two states are different. |
_CrtMemDumpStatistics | Dumps a given _CrtMemState structure. The structure may contain a snapshot of the state of the debug heap at a given moment or the difference between two snapshots. |
_CrtMemDumpAllObjectsSince | Dumps information about all objects allocated since a given snapshot was taken of the heap or from the start of execution. Every time it dumps a _CLIENT_BLOCK block, it calls a hook function supplied by the application, if one has been installed using _CrtSetDumpClient. |
_CrtDumpMemoryLeaks | Determines whether any memory leaks occurred since the start of program execution and, if so, dumps all allocated objects. Every time _CrtDumpMemoryLeaks dumps a _CLIENT_BLOCK block, it calls a hook function supplied by the application, if one has been installed using _CrtSetDumpClient. |
Track Heap Allocation Requests
Although pinpointing the source file name and line number at which an assert or reporting macro executes is often very useful in locating the cause of a problem, the same is not as likely to be true of heap allocation functions. While macros can be inserted at many appropriate points in an application's logic tree, an allocation is often buried in a special routine that is called from many different places at many different times. The question is usually not what line of code made a bad allocation, but rather which one of the thousands of allocations made by that line of code was bad and why.
Unique Allocation Request Numbers and _crtBreakAlloc
The simplest way to identify the specific heap allocation call that went bad is to take advantage of the unique allocation request number associated with each block in the debug heap. When information about a block is reported by one of the dump functions, this allocation request number is enclosed in braces (for example, '{36}').
Once you know the allocation request number of an improperly allocated block, you can pass this number to _CrtSetBreakAlloc to create a breakpoint. Execution will break just before allocating the block, and you can backtrack to determine what routine was responsible for the bad call. To avoid recompiling, you can accomplish the same thing in the debugger by setting _crtBreakAlloc to the allocation request number you are interested in.
Creating Debug Versions of Your Allocation Routines
A somewhat more complicated approach is to create Debug versions of your own allocation routines, comparable to the _dbg versions of the heap allocation functions. You can then pass source file and line number arguments through to the underlying heap allocation routines, and you will immediately be able to see where a bad allocation originated.
For example, suppose your application contains a commonly used routine similar to the following:
In a header file, you could add code such as the following:
Next, you could change the allocation in your record-creation routine as follows:
Now the source file name and line number where
addNewRecord
was called will be stored in each resulting block allocated in the debug heap and will be reported when that block is examined.