How to detect and isolate memory leaks

Source: Internet
Author: User
Tags exit in
Use Microsoft Visual C ++ to detect and isolate memory leaks
Introduction
The ability to dynamically allocate and release memory is one of the important features of the C/C ++ programming language, but Sun Tzu, a Chinese philosopher, pointed out that the most powerful and fragile. This is certainly true for C/C ++ applications. memory management errors are often one of the origins of bugs. One of the very subtle and difficult bugs to detect is the memory leak-the allocated memory cannot be correctly allocated. A slight memory leak that occurs only once cannot be noticed, but a program that leaks a large amount of memory or a growing number of leaks may show signs from poor (and slowly decreasing) performance to memory insufficiency and complete failure. Even worse, a program with a leak may occupy a lot of memory, causing another program to fail, leaving users with nothing to know about the problem. In addition, a serious memory leak may even be a symptom of other problems.

Fortunately, Visual C ++ debugger and CRT libraries provide you with a series of effective tools to detect and identify memory leaks. This article explains how to use these tools to effectively isolate 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 include description must be described in sequence. If you change the order, Your function may not work properly. _ Malloc_dbg and _ free_dbg, which contain crtdbg. H, map the malloc and free functions to the test version, and track memory allocation and release. This ing only happens in a test system (that is, only when _ debug is defined ). The released system uses the usual malloc and free features.

# Define: map the low-level version of the CRT heap function to the corresponding test version. This description is unnecessary, but without it, memory leakage only contains little useful information.

Once you have added the preceding description, you can release the memory information by including the following description in your program:

_ Crtdumpmemoryleaks ();
When you run your program during debugging, _ crtdumpmemoryleaks In the debug tag of the output window shows Memory leakage information. The memory leakage information is similar to the following:

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 you do not use # DEFINE _ crtdbg_map_alloc, the memory vulnerability heap is similar to the following:

Detected memory leaks!

Dumping objects->

{18} normal block at 0x00780e80, 64 bytes long.

Data: <> CD

Object dump complete.

As you know, when _ crtdbg_map_alloc is defined, _ crtdumpmemoryleaks gives you more useful information. If _ crtdbg_map_alloc is not defined, it will be shown 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)
When _ crtdbg_map_alloc is defined, the displayed content also shows you the files where the leaked memory is allocated. The number (20, for example,) following the file name is the row value in the file. If you double-click the output row that contains the row value and file name,

C:/program files/Visual Studio/myprojects/leaktest. cpp (20): {18} normal block at 0x00780e80, 64 bytes long.

The pointer will jump to the row where the memory is allocated in the source file (in the above case, the row number of leaktest. cpp is 20 ). Selecting the output row and pressing F4.

Use _ crtsetdbgflag
If your program always exists in the same place, it is very easy to call _ crtdumpmemoryleaks. However, what if your program needs to exit in multiple locations? If you do not 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 your program exits, it automatically calls _ crtdumpmemoryleaks. You must set two bit fields: _ crtdbg_alloc_mem_df and _ crtdbg_leak_check_df, as described previously.

Types of Translation Memory Modules
As stated earlier, the memory leakage information identifies each module of the leaked memory as a common module, a customer module, or a CRT module. In fact, common modules and customer modules are the only types you may pay attention.

A normal block is the normal memory allocated by your program.
A client block is a special memory module. It is used by Microsoft Foundation Classes (MFC) because it requires an destructor object. The MFC new operation creates a common module or a customer module, which is suitable for the created module.
A ctr module is a memory module allocated by the CRT library. The CRT Library manages the allocation of these modules, so you cannot notice this in the memory leak report unless there are serious errors in some places (for example, the CRT library crashes ).
There are two types of modules that you have never seen before in the memory leakage information:

The free block is a released memory module. The ignore block is a module that you have marked so specially that it will not appear in the memory leak report.

Set the CRT Report Style
As previously described, by default, _ crtdumpmemoryleaks dumps Memory leakage information to the debug pane of the output window. You can use _ crtsetreportmode to reset it to the heap location and to another location. If you use a library, it may reset the output to another location. In this case, you can use the following instructions to set the output position to return to the output window:

_ Crtsetreportmode (_ crt_error, _ crtdbg_mode_debug );

To use _ crtsetreportmode to send output information to another location, you must refer to the _ crtsetreportmode section of the Visual C ++ file.

Set a breakpoint at the number of memory allocations
In the memory leak report, the file name and row number can tell you that the leaked content exists and is allocated. However, it is not always sufficient to identify the problems. During a program running, a allocation is often called many times, but it may leak memory in a certain call. To determine the problem, you must know not only the leak exists in the allocation, but also the condition of the leak. For you, the information that makes it possible is the memory allocation number. When those are displayed, the file name and the row number are followed, which is a value that appears in curly brace. For example, in the output below, "18" is the memory allocation number. It means that the leaked memory is the 18th modules allocated by the memory in your program.

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.

The CRT library calculates the memory modules allocated during the running of the program, including the memory allocated by the CRT itself or other modules such as MFC. Therefore, an object with allocation number n is the nth object allocated in your program, but it cannot be the nth object allocated by the Code. (In most cases, it does not .)

You can use the allocation number to set a breakpoint at the place where the memory is allocated. To do this, you can set a position breakpoint very close to the beginning of your program. When your program is paused at that point, you can set such a position breakpoint from the quickwatch dialog box or the Watch window. For example, in the watch window, type the following expression in the name column:

_ Crtbreakalloc

If you are using the multi-threaded dynamic-link library (DLL) version of the CRT library, you must include the context operator, as described here:

{, Msvcrtd. dll} _ crtbreakalloc

Now, press return. The debugger evaluates the call and places the result in the value column. If you have not set any breakpoints during memory allocation, the value is-1. Replace the value in the value table with the value allocated in the memory where you want to interrupt-for example, 18 to interrupt the early distribution displayed in the output process.

After you set a breakpoint in the memory allocation area you are interested in, you can continue debugging. In the same conditions as before, you must be careful when running the program, so the allocation order will not change. When your program is interrupted at a special memory allocation point, you can view the call Stack window and other test information to determine the memory allocation under this condition. If necessary, you can continue to execute the program from that point, so that you can understand what happened to the object, and you may also be sure to not be correctly allocated. (It is helpful to set a data breakpoint for an object .)

Although it is easier to set memory allocation breakpoints in the debugger, you can 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 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, _ 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 import this structure to the _ crtmemdumpstatistics function to unload the content of any point in 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.

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 );

As the name implies, _ crtmemdifference compares two memory States (the first two parameters) and produces a result different from these two States (the third parameter ). Comparing the _ crtmemcheckpoint call at the beginning and end of your program 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.

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.