Use VC to detect and isolate memory leaks
[Author: wzhing entry: Chia Date: 2004-09-26 Download: Download attachment]
1 Introduction
The ability to have dynamic allocation and release of memory is one of the important features of the C / C program language, but China's philosopher grandson pointed out that the most powerful is also the most vulnerable. This is of course correct for C / C applications, and memory management errors is usually one of the origins of bugs. One of the BUGs that are very subtle and difficult to detect is memory leaks - cannot correctly allocate allocated memory. A slight memory leak can not be attractable, but leaks a large number of memory or increasing leaks may exhibit signs, from poor (and slowly) performance to insufficient memory. Dorse, a leak-leaking program may occupy a lot of memory so that another program is out of mind, just nothing to do with the problem. In addition, a severe memory leak may even be a sign of other issues.
Fortunately, the Visual C Debugger and CRT libraries offer you a series of effective tools that effectively detect and identify memory leaks. This article describes how to use these tools to effectively and systematically isolate memory.
2, set memory leak detection
The basic tool for detecting memory leaks is the debugger and CRT debug heap function. In order to use the debug heap function, you must contain the following description in your program:
#define _CRTDBG_MAP_ALLOC #include
#include Description must be described in order. If you change the order, the functions you use may not work properly. The _malloc_dbg and _free_dbg containing crtdbg.h map Malloc and Free functions to the beta, which tracks the allocation and release of memory. This mapping only occurs in a test system (that is, when _debug is defined). The released system uses the usual Malloc and Free function.
#DEfine Description Mapping the low version of the CRT heap function to the corresponding test version. This explanation is not required, but without it, the memory leak is only there is not much information.
Once you have added youna, you can release memory information by including the following instructions in your program:
_CRTDUMPMEMORYLEAKS ();
As you know, when _crtdbg_map_alloc is defined, _CRTDUMPMEMORYLEAKS gives you more useful information. If _crtdbg_map_alloc is not defined, then it will be displayed as follows:
Memory allocation value (within the curneth)
Module type (Normal, Client or CRT)
Memory positioned in hexadecimal format
Size of bytes modules
The first sixteen-byte content (you can use hexadecimal)
When defining _crtdbg_map_alloc, the displayed content also shows you the files assigned by the leak memory. The numbers (20, take this as an example for this) after the file name are the number of lines in the file. If you double-click the output line containing the row value and the file name,
You can see in the attachments this article:
#define _CRTDBG_MAP_ALLOC #include
3, use _crtsetdbgflag
In fact, it is enough to understand you, but if your program is always in the same place, it is easy to call _CRTDUmpMemoryLeaks. However, if your program needs to exit in multiple locations? If _CRTDUMPMEMORYLEAKS is not called at each possible exit, you can include the following calls at your program:
_CRTSETDBGFLAG (_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
This instructions are automatically called when your program exits _CRTDUMPMEMORYLEAKS. You have to set two bitmines, _CRTDBG_ALLOC_MEM_DF and _CRTDBG_LEAK_CHECK_DF, just as previously described.
4, translation memory module type
Like an early statement, memory leak information identifies each module of the leak memory as a normal module, a client module or a CRT module. In fact, ordinary modules and customer modules are the only type you may pay attention to.
A Client Block is a special memory module that is used by Microsoft Foundation Classes (MFC) due to an object of a destructor. The MFC New operator establishes a normal module or a client module to fit the created module.
A CTR module is a memory module allocated by the CRT library. The CRT library manages these modules to manage your own deregistration, so you can't notice this in the memory leak report, unless some places have a serious error (for example, CRT library collapse).
There are two types that you have never seen in memory leak information:
Free Block is a module that is released memory module Ignore Block is a module that you have already tagged over to occur in the memory leak report.
5, set the CRT report style
Like the previous description, press the default mode, _CRTDUMPMEMORYLEAKS Dump memory leak information to the Debug pane of the output window. You can use _CRTSetReportMode to reset it to the stack to another location. If you use a library, it may reset the output to another. In this case, you can use the following description to set the output location to return to the output window:
_CRTSetReportMode (_CRT_ERROR, _CRTDBG_MODE_DEBUG);
About using _CRTSetReportMode to send output information to another location, see the _CRTSetReportMode section of the Visual C file.
6, set a breakpoint at the number of memory allocations
The file names and line numbers in the memory leak report can tell you that the inner existence of leaks is all assigned, but understanding the allocation of the inner existence is not always sufficient for identification issues. During a program run, it is often a distribution that will be called many times, but it may leak memory in a certain call. In order to determine the problem, you must not only know the inner existence of the leak, but also know the conditions that leaks. For you, the information that makes it possible is the memory allocation number. This is the value that appears in Curly Brace when the file names and line numbers are displayed. For example, in the output below, "18" is a memory distribution number. It means that the leak memory is the 18th module of memory allocation in your program. Detected Memory Leaks!
DUMPING OBJECTS ->
C: / Program Files / Visual Studio / MyProjects / LeakTest / LeakTest.cpp (20): {18} Normal Block AT 0x00780E80, 64 BYTES Long.
Data: <> CD CD CD CD CD CD CD CD CD CD CD CD CD
Object Dump Complete.
The CRT library calculates the memory modules allocated during program operation, including CRT you allocate memory or other modules such as MFC. Therefore, an object with the allocation number N is the Nth object assigned in your program, but it is impossible to be nth object assigned by the code. (In most cases, it will not.)
You can set a breakpoint using the assigned number in the memory allocation. To do this, you can start close to your program, set a location breakpoint. When your program is paused, you can set a bit breakpoint from the QuickWatch dialog or Watch window. For example, in the Watch window, type the following expression at the NAME field:
_CRTBREAKALLOC
If you are using the multithreaded Dynamic-Link Library version of the CRT library, you must contain context operators, as described here:
{, MSVCRTD.DLL} _CRTBreakalloc
Now, press Return. The debugger evaluation is called and placed the result in the Value column. If you have not set any breakpoints in the memory allocation, then this value is -1. Use the allocation value you want to interrupt to replace the value in the Value table - for example, 18 to interrupt the assignment in the output during the output.
When you set a breakpoint after you are interested in the memory allocation, you can continue to debug. Be careful when running the program under the same conditions as before, and thus the order of assignments will not change. When your program is interrupted in a special memory allocation point, you can view the Call Stack window and other test information to determine the allocation of memory under this condition. If needed, you can continue the program from that point so that what happened to the object, and it is also possible to determine that it is not properly assigned. (It is very helpful for setting up a data breakpoint to objects.)
Although it is usually easier to set up memory allocation breaks in the debugger, if you like, you can set them in your code. In order to set a memory allocation breakpoint in your code, you can add such a line (for the eighteenth memory allocation):
_CRTBREAKALLOC = 18;
Most option, you can use the _crtsetbreakalloc function with the same effect.
_CRTSETBREAKALLOC (18);
7, compare memory status
Another way to locate memory leaks is to make snapshots on the memory status of the application in a key point. The CRT library provides a structural type, _CRTMemState. You can use it to store a snapshot of the memory status. _CRTMEMSTATE S1, S2, S3;
In order to snapakap up in a specific point, a _crtMemState structure to the He _CRTMEMCHECKPOINT function can be passed. This function fills this structure with a snapshot of the memory status at the time:
_CRTMEMCHECKPOINT (& S1);
You can pass this structure to the _crtmemdumpstatistics function to tip any point of the _CRTMemState structure:
_CRTMEMDUMPSTATISTICS (& S3); & 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.
In order to determine if a memory leak appears in a section code, you can make a snapshot of the memory status before and after this section, then compare two states with _CRTMEMDIFCERENCE:
_CRTMEMCHECKPOINT (& S1);
//Memory Allocations Take Place Here
_CRTMemcheckPoint (& S2);
IF (_CRTMEMDIFERENCE (& S3, & S1, & S2))
_CRTMEMDUMPSTATISTICS (& S3);
Like a name implied, _CRTMEMDIFerence compares two memory status (the first two parameters) and produces a result of different than these two states (third parameter). The _CRTMemCheckPoint calls and makes _CRTMEMDIFCERENCE comparison to detect memory leaks provide another method for detecting memory leaks. If a leak is detected, you can use the _CRTMemCheckPoint call to split your program and use binary binary search technique to locate the leak.