C/C ++ Memory leakage and Detection

Source: Internet
Author: User
Tags valgrind

"There is a memory leakage problem in the damn system." due to various factors in the project, there are always complaints about memory leaks. After the system has been running for a long time, there will be fewer and fewer available memory, some services may even fail. Memory leakage is one of the most difficult common errors, because it will not cause any problems unless the memory is used up or the malloc call fails. In fact, when C/C ++ is used in a language without a garbage collection mechanism, you spend a lot of time processing how to release the memory correctly. If the program runs for a long enough time, for example, if the background process runs on the server, as long as the server does not go down, a small mistake will also have a major impact on the program, some key services may fail.

I have a deep understanding of Memory leakage! During the internship, there was a memory leakage problem in the company's project. The project code was very large and there were many background processes, which made it hard to find the location of Memory leakage. This opportunity is for me to find out how to solve the memory leakage problem. I have some experience and have conducted some experiments later. Here I will share with you how to debug and find the memory leakage. The main content is as follows:

  • 1. Introduction to memory leakage
  • 2. Memory leakage detection on Windows
    • 2.1 check for Memory leakage
    • 2.2. Locate specific memory leaks
  • 3. Memory leakage detection in Linux
  • 4. Summary

In fact, the memory detection in Windows and Linux can be introduced in detail separately. Methods and tools are far more than described in this article, and my methods are not optimal, if you have a better method, please let me know.

1. Introduction and consequences of Memory leakage

Wikipedia defines Memory leakage as follows: in computer science, memory leakage refers to the failure of programs to release memory that is no longer in use due to negligence or errors. Memory leakage does not mean that the internal memory disappears physically, but that, after an application allocates a certain segment of memory, due to design errors, the memory will be lost before it is released, this results in a waste of memory.

One of the most difficult and hard-to-detect errors is the memory leakage, which means the bug of failing to correctly release the previously allocated memory. A small memory leak occurs only once and may not be noticed, but programs that leak a large amount of memory or programs that leak an increasing number of programs may show a variety of signs: from poor performance (and gradually decrease) to the memory used up completely. Worse, the leaked program may use too much memory, so that another program fails, and the user cannot find the real root cause of the problem. In addition, even harmless memory leaks may be a symptom of other problems.

Memory leakage may reduce the number of available memory to reduce computer performance. In the end, in the worst case, too much available memory is allocated, causing all or some devices to stop working normally or applications to crash. Memory leakage may not be serious and can even be detected by conventional means. In modern operating systems, an application is released upon termination of a regular internal program used by the application. This indicates that memory leakage in a transient running application will not cause serious consequences.

Memory leakage causes serious consequences in the following scenarios:

  • After running the program, you can ignore it and consume more and more memory (such as background tasks on the server, especially background tasks in embedded systems) with the loss of time, these tasks may be ignored for many years after running );
  • New memory is frequently allocated, for example, when a computer game or animated video screen is displayed;
  • The program can request unreleased memory (such as shared memory), or even terminate the program;
  • Leakage occurs inside the operating system;
  • Leakage occurs in key drive of the system;
  • Memory is very limited, such as in embedded systems or portable devices;
  • When running on an operating system (such as amigaos) where the memory is not automatically released at the time of termination, and once lost, it can only be restored by restarting.

The following example shows how to detect memory leakage:

 # Include <stdlib. h> <br/> # include <iostream> </P> <p> using namespace STD; </P> <p> void getmemory (char * P, int num) <br/>{< br/> P = (char *) malloc (sizeof (char) * num ); // use new to detect <br/>}</P> <p> int main (INT argc, char ** argv) <br/>{< br/> char * STR = NULL; <br/> getmemory (STR, 100); <br/> cout <"Memory Leak test! "<Endl; <br/> // If the while loop in main calls getmemory <br/> // The problem will become very serious <br/> // while (1) {getmemory (...);} <br/> return 0; <br/>}

In practice, it is impossible to be so simple. If it is so simple, there is no need for other methods. The programmer can see the problem at a Glance. This program is only used for testing.

2. Detect memory leaks on Windows 2.1 and check for memory leaks

The Visual Studio debugger and C Runtime (CRT) Libraries in Windows provide us with effective methods to detect and identify memory leaks. The principles are as follows: memory allocation should be implemented through the CRT at runtime, as long as the records are recorded separately when the memory is allocated and the memory is released, when the program ends, you can check whether there is a memory leakage by comparing the memory allocated and the memory released records. The following describes how to enable memory detection in:

  • Step 1: Include the following statements in the program: (# The include statement must follow the sequence shown above. If the order is changed, the function used may not work properly .)

 # DEFINE _ crtdbg_map_alloc <br/> # include <stdlib. h> <br/> # include <crtdbg. h>

By including crtdbg. H, the malloc and free functions are mapped to their debugging versions, namely _ malloc_dbg and _ free_dbg, which track memory allocation and release. This ing is only available in the debug version (where_ Debug. Release a normal versionMallocAndFreeFunction.

# The define statement maps the basic version of the CRT heap function to the corresponding debug version. This statement is not absolutely required, but without it, the memory leak dump contains less useful information.

  • Step 2: After the preceding statements are added, you can dump the memory leakage information by including the following statements in the Program (usually before the program exits:
  _ Crtdumpmemoryleaks ();

The complete code is as follows:

# DEFINE _ crtdbg_map_alloc <br/> # include <stdlib. h> <br/> # include <crtdbg. h> </P> <p> # include <iostream> </P> <p> using namespace STD; </P> <p> void getmemory (char * P, int num) <br/>{< br/> P = (char *) malloc (sizeof (char) * num ); <br/>}</P> <p> int main (INT argc, char ** argv) <br/>{< br/> char * STR = NULL; <br/> getmemory (STR, 100); <br/> cout <"Memory Leak test! "<Endl; </P> <p> _ crtdumpmemoryleaks (); </P> <p> return 0; <br/>}When running a program in the debugger, _ crtdumpmemoryleaks will display Memory leakage information in the "output" window. The memory leakage information is as follows:

If the # DEFINE _ crtdbg_map_alloc statement is not used, the memory leakage dump is as follows:

When _ crtdbg_map_alloc is not defined, the displayed information is:

  • Memory Allocation Number (in braces ).

  • Block Type (common, client, or CRT ).

  • "Normal block" is the general memory allocated by the program.

  • "Client block" is a special type of memory block used by the MFC program for objects that require destructor. The MFC new operation creates a common block or client block based on the needs of the object being created.

  • "CRT block" is the memory block allocated by the CRT library for your own use. The CRT library handles the release of these blocks, so it is unlikely that you will see these blocks in the memory leak report unless serious errors (such as CRT library corruption) occur ).

The following two block types are not displayed in the memory leakage information:

  • "Available blocks" are released memory blocks.

  • The ignore block is a block that you have specifically marked, so it does not appear in the memory leak report.

  • Memory location in hexadecimal format.

  • The block size in bytes.

  • The content of the first 16 bytes (also in hexadecimal format ).

When _ crtdbg_map_alloc is defined, files with leaked memory allocated are displayed. The number in the brackets after the file name (10 in this example) is the row number in the file.

Note: If the program always exits at the same position, it is very easy to call _ crtdumpmemoryleaks. If the program exits from multiple locations, you do not need to place_ CrtdumpmemoryleaksBut can include the following calls at the beginning of the program:

_ Crtsetdbgflag (_ crtdbg_alloc_mem_df | _ crtdbg_leak_check_df );

This statement is automatically called when the program exits._ Crtdumpmemoryleaks. Must be set at the same time_ Crtdbg_alloc_mem_dfAnd_ Crtdbg_leak_check_dfThe two bit fields are shown in the preceding figure.

2.2. Locate specific memory leaks

Through the above method, we can almost find out where to call the memory allocation functions malloc and new. In the above example, the getmemory function contains 10th rows! However, it cannot be located where getmemory () is called to cause memory leakage, and there may be many calls to getmemory in large projects. How can I locate the location where getmemory is called to cause memory leakage?

Another technique for locating memory leaks involves taking snapshots of the memory status of applications at critical points. The CRT Library provides a structure type_ CrtmemstateYou can use it to store snapshots of memory status:

_ Crtmemstate S1, S2, S3;

To take a snapshot of the memory status at a specified point, pass it to the _ crtmemcheckpoint function._ CrtmemstateStructure. This function fills the structure with snapshots in the current memory status:

_ Crtmemcheckpoint (& S1 );

Passed to the _ crtmemdumpstatistics Function_ CrtmemstateStructure, which can be dumped at any point in mind:

_ Crtmemdumpstatistics (& S1 );

To determine whether a part of the Code has a memory leak, you can take a snapshot of the memory status before and after the part, and then use _ crtmemdifference to compare the two states:

_ Crtmemcheckpoint (& S1); <br/> // memory allocations take place here <br/> _ crtmemcheckpoint (& S2 ); </P> <p> If (_ crtmemdifference (& S3, & S1, & S2) <br/> _ crtmemdumpstatistics (& S3); <br/>

As the name suggests,_ CrtmemdifferenceCompare two memory states (S1 and S2) to generate the result of the difference between the two States (S3 ). Place at the beginning and end of the program_ CrtmemcheckpointCall and use_ CrtmemdifferenceThe comparison result is another way to check memory leakage. If leakage is detected, you can use_ CrtmemcheckpointThe binary search technology is called to divide programs and locate leaks.

In the above example, we can locate the exact call to getmemory:

# DEFINE _ crtdbg_map_alloc <br/> # include <stdlib. h> <br/> # include <crtdbg. h> </P> <p> # include <iostream> <br/> using namespace STD; </P> <p> _ crtmemstate S1, S2, S3; </P> <p> void getmemory (char * P, int num) <br/>{< br/> P = (char *) malloc (sizeof (char) * num); <br/>}</P> <p> int main (INT argc, char ** argv) <br/>{< br/> _ crtmemcheckpoint (& S1); <br/> char * STR = NULL; <br/> getmemory (STR, 100 ); <br/> _ crtmem Checkpoint (& S2); <br/> If (_ crtmemdifference (& S3, & S1, & S2) <br/> _ crtmemdumpstatistics (& S3 ); <br/> cout <"Memory Leak test! "<Endl; <br/> _ crtdumpmemoryleaks (); <br/> return 0; <br/>}< br/>

During debugging, the program outputs the following results:

This indicates that memory leakage exists between S1 and S2 !!! If getmemory is not called between S1 and S2, no information is output.

3. Memory leakage detection in Linux

As described above, in Vs, the code "contains crtdbg. h. Map the malloc and free functions to their debugging versions, namely _ malloc_dbg and _ free_dbg. These two functions track memory allocation and release. This ing is only available in the debug version (where_ Debug. Release a normal versionMallocAndFreeFunction ." This hooks malloc and free are used to record memory allocation information.

In Linux, mtrace, http://en.wikipedia.org/wiki/mtrace. The method is similar. I will not describe it here. This section describes valgrind, a very powerful tool. As shown in:

As shown in:

= 6118 = 100 bytes in 1 blocks are definitely lost in loss record 1 of 1
= 6118 = at 0x4024f20: malloc (vg_replace_malloc.c: 236)
= 6118 = by 0x8048724: getmemory (char *, INT) (IN/home/Netsky/workspace/a. out)
= 6118 = by 0x804874e: Main (in/home/Netsky/workspace/a. out)

Getmemory is called in main to cause memory leakage. getmemory calls malloc to cause 100 bytes of Memory leakage.

Things to notice:
• There is a lot of information in each error message; read it carefully.
• The 6118 is the process ID; it's usually unimportant.
• The specified rst line ("heap summary") tells you what kind of error it is.
• Below the specified rst line is a stack trace telling you where the problem occurred. stack traces can get quite large, and be
Confusing, especially if you are using the C ++ STL. Reading them from the bottom up can help.

• The Code addresses (eg. 0x4024f20) are usually unimportant, but occasionally crucial for tracking down weirder
Bugs.

The stack trace tells you where the leaked memory was allocated. memcheck cannot tell you why the memory leaked,
Unfortunately. (ignore the "vg_replace_malloc.c", that's an implementation detail .)
There are several kinds of leaks; the two most important categories are:
• "De shortnitely lost": Your program is leaking memory -- snapshot X it!
• "Probably lost": Your program is leaking memory, unless you're doing funny things with pointers (such as moving
Them to point to the middle of a heap block)

For more information about valgrind, see http://valgrind.org/docs/manual/manual.html.

4. Summary

In fact, the reason for Memory leakage can be summarized as: the memory application operations such as malloc/New are called, but the corresponding free/delete operations are missing. In short, malloc/New is more than free/Delete. We need to pay attention to this point during programming to ensure that each malloc has a corresponding free, and each new has a corresponding deleted !!! We usually need to develop such a good habit.

To avoid Memory leakage, We can summarize the following points:

  • Programmers should develop good habits to ensure that malloc/New and free/delete match;
  • The key principle for detecting memory leaks is to check whether malloc/New and free/delete match. Some tools also use this principle. To achieve this, a macro or hook is used to add a layer between the user program and the Runtime Library to record the memory allocation.
Related Article

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.