The ability to dynamically allocate and release memory is one of the important features of the C/C ++ programming language. The VisualC ++ debugger and CRT libraries provide a series of effective tools to detect and identify memory leaks.
Set Memory leakage detection
The basic tool used to detect memory leaks is the debugger and CRT to debug heap functions. To use the debug heap function, you must include the following description in your program:
# DEFINE _ crtdbg_map_alloc # Include <stdlib. h> # Include <crtdbg. h> |
The Order stated above must be ensured. If the order is changed, it may not work properly. The _ malloc_dbg and _ free_dbg of <crtdbg. h> Replace the standard malloc and free functions in the debug version, which can track the distribution and release of memory. However, this only happens in the debug version (when # DEFINE _ debug is used), while the release version still uses the standard malloc and free functions.
# DEFINE _ crtdbg_map_alloc indicates the corresponding debug version of the CRT heap function. This definition is not mandatory, but without it, the memory leak report only contains useless information.
Once you have added the Declaration just now, you can report Memory leakage by adding the following code to the program:
When running a program in debug mode, _ crtdumpmemoryleaks In the debug tag of the output window will display Memory leakage information, for example:
Detected memory leaks! Dumping objects-> C:/program files/Visual Studio/myprojects/leaktest. cpp (20): {18} normal block at 0x00780e80, 64 bytes long. Data: <> CD Object dump complete. |
If no # DEFINE _ crtdbg_map_alloc is available, the memory leakage report will look like the following:
Detected memory leaks! Dumping objects-> {18} normal block at 0x00780e80, 64 bytes long. Data: <> CD Object dump complete. |
It can be seen that when _ crtdbg_map_alloc is defined, _ crtdumpmemoryleaks can provide more useful information.
If _ crtdbg_map_alloc is not defined, the memory leakage report is as follows:
Memory Allocation value (in curly brackets)
Module type (normal, client, or CRT)
Memory located in hexadecimal format
The size of the module in bytes
The content of the first sixteen bytes (or in hexadecimal format)
If _ crtdbg_map_alloc is defined, the report also contains files allocated with leaked memory. The number in the brackets after the file name is the row value in the file.
Double-click the output row containing the row value and file name, or select the output row and press F4:
C:/program files/Visual Studio/myprojects/leaktest. cpp (20): {18} normal block at 0x00780e80, 64 bytes long.
The edit window will jump to the Code row in which the leaked memory is allocated in the file, and the row with the row number 20 in leaktest. cpp.
Use _ crtsetdbgflag
If your program exits in only one place, it is very easy to choose to call _ crtdumpmemoryleaks. However, what if your program may exit in multiple places? If you do not want to call _ crtdumpmemoryleaks at every possible exit, you can include the following calls at the beginning of your program:
_ Crtsetdbgflag (_ crtdbg_alloc_mem_df | _ crtdbg_leak_check_df );
When the program exits, it will automatically call _ crtdumpmemoryleaks (_ crtdbg_alloc_mem_df and _ crtdbg_leak_check_df must be set ).
Types of Translation Memory Modules
In the memory leak report, the leaked memory is divided into common blocks, customer blocks, and CRT blocks. In fact, you only need to pay attention to the common block and customer block types.
Normal block: the memory allocated by your program.
Client block: a special memory block. It is an object used by MFC. When the program exits, the destructor of the object is not called. The MFC new operator can be used to create common blocks and customer blocks.
CRT block: it is the memory block allocated by the C Runtime Library for your own use. The CRT Library manages the allocation and release of these memories by itself. Generally, you will not find any CRT Memory leakage in the memory leakage report unless the program has a serious error (such as a CRT library crash ).
The following two types of memory blocks will not appear in the memory leak report:
Free block: a free block of memory.
Ignore block: it is a memory block explicitly declared by the programmer not to appear in the memory leak report.
Set the CRT Report Style
Usually _ crtdumpmemoryleaks () will dump the information leaked by the memory to the debug column of the output window. You can use _ crtsetreportmode () to reset the output to another position. For more details about how to use _ crtsetreportmode (), refer to msdn.
Set a breakpoint at the number of memory allocations
In the memory leak report, the file name and line number can tell the location of the leaked Memory code. However, this information is not enough to fully understand the cause of the leakage. When a program is running, a piece of code for allocating memory will be called many times, but it may be because the memory is not released after a certain call, leading to memory leakage. To ensure that the memory is not released, you must not only know the existence of the leak, but also know the conditions for leakage. For you, the helpful information is the Memory Allocation Number-the value displayed in the braces after the file name and row number.
For example, in the following output information, "18" indicates the Memory Allocation Number, indicating that the leaked memory is the 18th memory blocks allocated in your program:
Detected memory leaks! Dumping objects-> C:/program files/Visual Studio/myprojects/leaktest. cpp (20): {18} normal block 0x00780e80, 64 bytes long. Data: <> CD Object dump complete. |
The CRT library counts all memory modules allocated during the running of the program, including the memory allocated by the CRT itself or other modules allocated, such as MFC. Therefore, an object with allocation number n is the nth object allocated in your program, but it does not represent the nth object allocated by that code (in most cases, none of them .)
In this way, you can use the allocation number to set a breakpoint at the place where the memory is allocated. To set such an endpoint, you can set a breakpoint at the beginning of your program. When your program break at that point, you can set such a position breakpoint from the quickwatch dialog box or watch window.
For example, in the watch window, type the following expression in the name column:
If you are using a multi-threaded version of the CRT library dynamic-link library (DLL), you must include context operators, such:
| {, Msvcrtd. dll} _ crtbreakalloc |
Press the return key. The debugger finds the value and places the result in the value column. If you have not set any memory allocation breakpoint during the memory allocation process, the value is-1. Replace the value in the value table with the allocated value of the memory you want to interrupt-for example, 18.
After the memory allocation breakpoint is set, continue debugging. At this time, be careful when running the program, and ensure that the order of memory block allocation will not change. When your program is interrupted at the memory allocation point, you can view the call Stack window and other debug information to analyze the cause of the leak. You can continue to execute the program from that point so that you can understand what happened and determine why the memory is not released (it is helpful to set a memory allocation breakpoint ).
Although it is easier to set memory allocation breakpoints in the debugger, you can also set them in your code if you like. To set a memory allocation breakpoint in your code, you can add such a line (for 18th memory allocations ):
You can also use the _ crtsetbreakalloc function with the same effect:
Compare memory status
Another way to locate Memory leakage is to take a snapshot of the memory status of the application at a critical point. The CRT Library provides a structure type of _ crtmemstate. You can use it to store a snapshot of the memory status:
| _ Crtmemstate S1, S2, S3; |
To take a snapshot of the memory status at a specific point, you can transmit a _ crtmemstate structure to the he _ crtmemcheckpoint function. This function uses a snapshot of the current memory status to fill the structure:
| _ Crtmemcheckpoint (& S1 ); |
You can pass this structure to the _ crtmemdumpstatistics function to dump any point in the _ crtmemstate structure:
| _ Crtmemdumpstatistics (& S1 ); |
This function prints a pile of memory allocation information similar to the following:
0 bytes in 0 free blocks. 0 bytes in 0 normal blocks. 3071 bytes in 16 CRT blocks. 0 bytes in 0 ignore blocks. 0 bytes in 0 client blocks. Largest number used: 3071 bytes. Total allocations: 3764 bytes. |
To determine whether a memory leak occurs in a code section, you can take a snapshot of the memory status before and after this section, and then use _ crtmemdifference to compare the two states:
| _ Crtmemcheckpoint (& S1 ); // Memory allocations take place here ...... _ Crtmemcheckpoint (& S2 ); If (_ crtmemdifference (& S3, & S1, & S2 )) _ Crtmemdumpstatistics (& S3 ); |
From the name, we can know that _ crtmemdifference is used to compare two memory States (the last two parameters) and return the result of status difference (the first parameter ). Comparing the _ crtmemcheckpoint call at the beginning and end of your function with _ crtmemdifference provides another method for detecting memory leaks. If a leak is detected, use the _ crtmemcheckpoint call to split your program and use binary search technique to locate the leak.