VC uses the CRT debugging function to detect memory leakage

Source: Internet
Author: User
Tags exit in

Source: http://pcedu.pconline.com.cn/empolder/gj/vc/0506/648575_1.html

C/C ++Programming LanguageOne of the most powerful features of C/C ++ is its dynamic allocation and release of memory.ProgramThis sentence is exactly confirmed. During C/C ++ application development, improper processing of dynamically allocated memory is the most common problem. Among them, one of the most elusive and most difficult errors to detect is the memory leakage, that is, the error of failing to correctly release the previously allocated memory. Occasionally, a small amount of memory leakage may not attract our attention, but programs that leak a large amount of memory or leak an increasing number of programs may show a variety of symptoms: from poor performance (and gradually decreasing) to completely exhausted memory. Worse, the leaked program may use too much memory, causing another program to crash, making it impossible for users to find the real root cause of the problem. In addition, even harmless memory leaks may affect the pool.

Fortunately, the Visual Studio debugger and the C Runtime (CRT) library provide us with an effective way to detect and identify memory leaks. Share the following with me: How can I use the CRT debugging function to detect memory leaks?

I. How to enable the memory leakage detection mechanism

The default status of VC ++ ide does not enable the Memory Leak Detection mechanism.CodeMemory leakage occurs. The debug page of the output window of the debugging session does not output information about memory leakage. You must set two basic mechanisms to enable the Memory Leak Detection mechanism.

First, use the debug heap function:

# DEFINE _ crtdbg_map_alloc
# Include <stdlib. h>

# Include <crtdbg. h>

Note: # include statement order. If you change this order, the function used may not work properly.

By including the crtdbg. h header file, you can map the malloc and free functions to its "debug" version _ malloc_dbg and _ free_dbg. These functions track memory allocation and release. This ing is only valid for debugging (Debug) versions (that is, to define _ Debug. The release version (release) uses common malloc and free functions. # The define statement maps the basic version of the CRT heap function to the corresponding "debug" version. This statement is not required, but if it is not available, the information about memory leakage will be incomplete.

The second is to add the following statement to output Memory leakage information where the memory leak needs to be detected:

_ Crtdumpmemoryleaks ();

When running a program in the debugger, _ crtdumpmemoryleaks will display Memory leakage information on the debug page of the output window. For example, detected memory leaks!

Dumping objects->

C: \ temp \ memleak. cpp (15): {45} normal block at 0x00441ba0, 2 bytes long.

Data: <AB> 41 42

C: \ Program Files \ Microsoft Visual Studio \ vc98 \ include \ crtdbg. H (552): {44} normal
Block at 0x00441bd0, 33 bytes long.

Data: <C> 00 43 00 CD

C: \ Program Files \ Microsoft Visual Studio \ vc98 \ include \ crtdbg. H (552): {43} normal
Block at 0x00441c20, 40 bytes long.

Data: <C> 08 02 43 00 16 00 00 00 00 00 00 00 00 00 00 00 00 00

Object dump complete.

If the # DEFINE _ crtdbg_map_alloc statement is not used, the output of Memory leakage is as follows:

Detected memory leaks!

Dumping objects->

{45} normal block at 0x00441ba0, 2 bytes long.
Data: <AB> 41 42

{44} normal block at 0x00441bd0, 33 bytes long.
Data: <C> 00 43 00 CD

{43} normal block at 0x00441c20, 40 bytes long.
Data: <C> C0 01 43 00 16 00 00 00 00 00 00 00 00 00 00 00 00 00

Object dump complete.

Based on this output, you cannot know which source program file has a memory leak. Next we will study the output information format. There is nothing to say about the first and second rows, starting from the third row:

XX}: the number in the arc is the memory allocation number. In this example, It is {45 },{ 44 },{ 43 };
Block: memory block type. There are three common types: normal (normal), client (client), or CRT (runtime). In this example, normal block is used;
Memory location in hexadecimal format, for example, at 0x00441ba0;
Memory block size in bytes, for example, 32 bytes long;
The content of the first 16 bytes (also expressed in hexadecimal format), for example, data: 41 42;

If _ crtdbg_map_alloc is defined, the file name for allocating leaked memory is displayed before the memory allocation sequence number, and the numbers in the brackets after the file name indicate the leaked code line number, for example:

C: \ temp \ memleak. cpp (15)

Double-click the output line of the file name in the output window to jump to the code line for allocating the memory to the source file (you can also select this line and press F4. The effect is the same ), in this way, it is easy to locate where memory leakage occurs. Therefore, _ crtdbg_map_alloc has obvious functions.

Use _ crtsetdbgflag
If the program has only one exit, it is easy to choose the location of the call _ crtdumpmemoryleaks. But what if the program may exit in multiple places? Calling _ crtdumpmemoryleaks at every possible exit is definitely not advisable, so the following call can be included at the beginning of the program: _ crtsetdbgflag (_ crtdbg_alloc_mem_df | _ crtdbg_leak_check_df ); this statement automatically calls _ crtdumpmemoryleaks no matter where the program exits. Note: You must set both the _ crtdbg_alloc_mem_df and _ crtdbg_leak_check_df bits.

Set the CRT report mode
By default, _ crtdumpmemoryleaks dumps Memory leakage information to the debug page of the output window. If you want to export this information to another place, you can use _ crtsetreportmode to reset it. If you use a library, it may direct the output to another location. In this case, you only need to use the following statement to set the output position back to the output window:

_ Crtsetreportmode (_ crt_error, _ crtdbg_mode_debug );

For more information about using _ crtsetreportmode, see the description of _ crtsetreportmode in the msdn library.

Ii. Explain the memory block type

As mentioned above, in the memory leak report, each leaked memory is divided into normal (common block), client (client block), and CRT block. In fact, you need to pay attention to normal and client blocks, that is, common blocks and client blocks.
1. Normal block (normal block): This is the memory allocated by your program.
2. Client block (customer block): This is a special type of memory block, which is specially used for the objects that require destructor in the MFC program. The MFC new operator can either create a common block for the created object or create a customer block for the object.
3. 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. we generally do not find the CRT Memory leakage in the memory leakage report unless the program has a serious error (such as the CRT library crash ).

In addition to the above types, there are two types of memory blocks that will not appear in the memory leakage report:
1. Free block: the memory block that has been released (free.
2. Ignore block (ignore block): This is a memory block explicitly declared by the programmer not to appear in the memory leak report.

3. How to set a breakpoint at the memory allocation sequence number

In the memory leak report, the file name and line number can tell the location of the leaked Memory code, but it is not enough to rely solely on this information to understand the complete cause of the leak. When a program is running, a piece of memory allocation code may be called many times, as long as the memory is not released after one call, it will cause memory leakage. To determine which memory is not released, you must know not only where the leaked memory is allocated, but also the conditions for leakage. In this case, the memory allocation sequence number is particularly useful-this sequence number is the number in the ARC after the file name and the row number.

For example, in the output information of the sample code in this article, "45" indicates the memory allocation sequence number, indicating that the leaked memory is the 45th memory blocks allocated in your program:

Detected memory leaks!

Dumping objects->

C: \ temp \ memleak. cpp (15): {45} normal block at 0x00441ba0, 2 bytes long.

Data: <AB> 41 42

......

Object dump complete.

The CRT library counts all memory blocks allocated during the running of the program, including the memory allocated by the CRT library itself and the memory allocated by other libraries (such as MFC. Therefore, an object with the allocation number n is the nth object allocated in the program, but not necessarily the nth object allocated by the Code. (This is not the case in most cases .) In this way, you can use the allocation sequence number to set a breakpoint at the location of the allocated memory. The method is to set a position breakpoint near the start of the program. When the program is interrupted at this point, you can set a memory allocation breakpoint in the quickwatch dialog box or watch window:

For example, in the watch window, type the following expression in the name column:

_ Crtbreakalloc

To use the multi-threaded dll version (/MD option) of the CRT library, the context operator must be included, as shown in the following code:

{, Msvcrtd. dll} _ crtbreakalloc

Press enter. The debugger calculates the value and places the result in the value column. If no breakpoint is set at the memory allocation point, the value is-1.

Replace the value in the value column with the Allocation Number of the memory allocation you want to interrupt at its location. For example, enter 45. This will interrupt the allocation where the serial number is 45.

You can continue debugging after a breakpoint is set at the memory allocation you are interested in. At this time, be careful when running the program, and ensure that the order of memory block allocation will not change. When the program is interrupted at the specified memory allocation, you can view the call Stack window and other debugger information to determine the memory allocation situation. If necessary, you can continue to execute the program from this point to see what happened to the object. You may be able to determine the cause of the incorrect object release.

Although it is usually easier to set memory allocation breakpoints in the debugger, you can also set these breakpoints in the Code if you want. To set a memory allocation breakpoint in the code, you can add such a line (for 45th memory allocations ):

_ Crtbreakalloc = 45;

You can also use the _ crtsetbreakalloc function with the same effect:

_ Crtsetbreakalloc (45 );

4. How to compare the memory status

Another way to locate Memory leakage is to obtain a snapshot of the application's memory status at a critical point. The CRT Library provides a structure type of _ crtmemstate. You can use it to store snapshots of memory status:

_ Crtmemstate S1, S2, S3;

To obtain a memory status snapshot at a specified point, you can pass a _ crtmemstate structure to the _ crtmemcheckpoint function. This function fills the structure with snapshots in the current memory status:

_ Crtmemcheckpoint (& S1 );

By passing the _ crtmemdumpstatistics structure to the _ crtmemstate function, you can dump the content of this structure anywhere:

_ Crtmemdumpstatistics (& S1 );

This function outputs dump memory allocation information in the following format:

0 bytes in 0 free blocks.
75 bytes in 3 normal blocks.
5037 bytes in 41 CRT blocks.
0 bytes in 0 ignore blocks.
0 bytes in 0 client blocks.
Largest number used: 5308 bytes.
Total allocations: 7559 bytes.

To determine whether memory leakage has occurred in a code segment, you can obtain the memory status snapshots before and after the code segment, and then use _ crtmemdifference to compare the two states:

_ Crtmemcheckpoint (& S1); // gets the first memory status Snapshot

// Allocate memory here

_ Crtmemcheckpoint (& S2); // gets the second memory status Snapshot

// Compare the differences between two memory snapshots
If (_ crtmemdifference (& S3, & S1, & S2 ))
_ Crtmemdumpstatistics (& S3); // dump difference result

As the name suggests, _ crtmemdifference compares two memory States (the first two parameters) and generates the result of the difference between the two States (the third parameter ). Put _ crtmemcheckpoint at the beginning and end of the program and use _ crtmemdifference to compare the results. This is another way to check memory leakage. If leakage is detected, you can use _ crtmemcheckpoint to call the binary search technology to split the program and locate the leakage.

V. Conclusion

Although VC ++ has a mechanism for debugging the MFC application, the memory allocation discussed above is very simple and does not involve the MFC object, so these contents are also suitable for the MFC program. You can find a lot of information about VC ++ debugging in the msdn library. If you can make good use of the msdn library, I believe that you may become a debugging master in a short time.

 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.