/*************************************** **************************************** ****
The basic tool used to detect memory leaks is the debugger and CRT to debug heap functions. To use the debug heap functionProgramYou must include the following description:
# 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> will replace the standard
The malloc and free functions of are available in the debug version. It can track the distribution and release of memory. But this will only happen in the debug version (when # define
_ Debug), while the release version still uses the standard malloc and free features.
# 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 add the followingCodeTo report Memory leakage information:
_ Crtdumpmemoryleaks ();
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 line where the leaked memory is allocated in the file, leaktest. the row whose row number is 20 in 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 (), see
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. Because when a program is running
The code for allocating segments to memory will be called many times, but it may be because the memory is not released after a call, resulting in 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:
_ Crtbreakalloc
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
Call
The Stack window and other debug information are used to analyze the cause of the leakage. 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 (Set
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 ):
_ Crtbreakalloc = 18;
You can also use the _ crtsetbreakalloc function with the same effect:
_ Crtsetbreakalloc (18 );
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 _ 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 ). In your function
Comparing the call of _ crtmemcheckpoint at the beginning and end with _ crtmemdifference provides another method for detecting memory leaks. If one is detected
You can use _ crtmemcheckpoint to split your program and use binary search technique to locate leaks.
**************************************** **************************************** *****/
# DEFINE _ crtdbg_map_alloc
# Include <stdlib. h>
# Include <crtdbg. h>
Int main ()
{
_ Crtsetdbgflag (_ crtdbg_alloc_mem_df | _ crtdbg_leak_check_df );
Widget * PW = new widget;
Double * P = new double (100 );
Return 0;
}
Detected memory leaks!
Dumping objects->
{55} normal block at 0x00395d28, 8 bytes long.
Data: <Y @> 00 00 00 00 00 59 40
{54} normal block at 0x00395ce8, 4 bytes long.
Data: <> 00 00 00 00
Object dump complete.
There is no information such as the file name and number of lines. There is only a memory address. You can find the memory leak in the debugging status by hitting the memory data breakpoint.
it is inconvenient to view the output window because there is too much output information, you can output debugging information such as memory leakage to a special file and add the following code at the beginning of the winmain () function:
# Ifdef _ debug
Handle hlogfile =: createfilea ("leak.txt", generic_write, file_pai_write | file_pai_read,
Null, create_always,
File_attribute_normal,
Null );
_ Crtsetreportmode (_ crt_warn, _ crtdbg_mode_file );
_ Crtsetreportfile (_ crt_warn, hlogfile );
_ Crtsetdbgflag (_ crtdbg_alloc_mem_df | _ crtdbg_leak_check_df );
# Endif
You can.