One of C ++ memory management (Memory leakage detection)

Source: Internet
Author: User

This article from http://blog.csdn.net/zxcred

A major part of the complexity of the C ++ program is its memory management. Without the garbage collection mechanism like C #, memory management is very difficult for beginners. Memory leakage often occurs. How can we avoid Memory leakage when writing programs? First, we need to know whether the program memory has been leaked, and then find out which line of code has been leaked in order to fix it.
This article describes how to detect memory leaks. The most important thing is how the pure C and C ++ programs detect memory leaks.
There are many professional detection tools, such as the well-known boundscheck, but these tools also have their shortcomings. I think boundscheck is commercial software first. Then you need to install it, which is not easy to use. This is because we may not always start the system to detect the vulnerability. In this way, many problems are often accumulated, and it will be difficult to solve them at that time. It is best to start coding and remind us of memory leaks at any time step by step. We often debug programming programs. If we can automatically detect memory leaks every time the program is debugged.

1. Detect Memory leakage in MFC
For example, it is very simple to use an MFC program. By default, the memory leakage detection function is available.
We used vs2005 to generate an MFC Dialog Box program and found that it can automatically detect memory leakage. we do not need to perform any special operations. after careful observation, the following code is found in each CPP file:

  1. # Ifdef _ debug
  2. # Define new debug_new
  3. # Endif

The macro debug_new is defined in the afx. h file, which helps us locate Memory leakage.

If the memory is not deleted after the CPP file contains the above Code is allocated, when the program is stopped, the output window of Visual Studio will display the following information:

  1. Detected memory leaks!
  2. Dumping objects->
  3. D:/code/mfctest. cpp (80): {157} normal block at 0x003af170, 4 bytes long.
  4. Data: <> 00 00 00 00
  5. Object dump complete.

Double-click the line in the output window, and IDE will open the file and locate the line. It is easy to see which memory leakage occurs.

2. Detect pure C ++ program memory leakage

I tried the Win32 console application and Win32 project projects created using Visual Studio, and the results cannot detect memory leakage.
Next, we will establish a mechanism for detecting program memory leaks.
First, we need to know that the debug version of the C Runtime Library provides a lot of detection functions, making it easier for us to debug programs. In msdn, there is a special chapter about this, called debug routines. We suggest you take a look at the content.
We will use several important functions. Among them, the most important thing is _ crtdumpmemoryleaks (). Let's take a look at the help in msdn. To use this function, you must include the header file crtdbg. h.
This function is only available in the debug version. When you run a program under the debugger, _ crtdumpmemoryleaks will display Memory leakage information in the "output" window. test the code by writing a segment, as shown below:
Detect memory leakage version 1:

  1. # Include "stdafx. H"
  2. # Include <crtdbg. h>
  3. Int _ tmain (INT argc, _ tchar * argv [])
  4. {
  5. Int * P = new int ();
  6. _ Crtdumpmemoryleaks ();
  7. Return 0;
  8. }

After running, the following information is displayed in the output window:

  1. Detected memory leaks!
  2. Dumping objects->
  3. {112} normal block at 0x003aa770, 4 bytes long.
  4. Data: <> 00 00 00 00
  5. Object dump complete.

However, this only tells us where the program memory is leaked and it cannot be seen at a glance.
Look at ourDetects Memory leakage Version 2:

  1. # Include "stdafx. H"
  2. # Ifdef _ debug
  3. # Define debug_clientblock new (_ client_block, _ file __, _ line __)
  4. # Else
  5. # Define debug_clientblock
  6. # Endif
  7. # DEFINE _ crtdbg_map_alloc
  8. # Include <crtdbg. h>
  9. # Ifdef _ debug
  10. # Define new debug_clientblock
  11. # Endif
  12. Int _ tmain (INT argc, _ tchar * argv [])
  13. {
  14. Int * P = new int ();
  15. _ Crtdumpmemoryleaks ();
  16. Return 0;
  17. }

The program defines several macros and replaces the new in the debug version with the new one. The new one records the file name and code line when new is called. after running, you can see the following results:

  1. Detected memory leaks!
  2. Dumping objects->
  3. D:/code/consoletest. cpp (21): {112} client block at 0x003a38b0, subtype 0, 4 bytes long.
  4. Data: <> 00 00 00 00
  5. Object dump complete.

Haha, it has the same effect as the MFC program, but wait. Let's take a look at the following code:

  1. Int _ tmain (INT argc, _ tchar * argv [])
  2. {
  3. Int * P = new int ();
  4. _ Crtdumpmemoryleaks ();
  5. Delete P;
  6. Return 0;
  7. }

After running, we can find that we have deleted the pointer, but it still reports Memory leakage. As you can imagine, Every time new is called, the program records the call internally, similar to an array record. If delete is used, it will be deleted from the array, _ crtdumpmemoryleaks () prints the current status of the array.
Therefore, in addition to dumping out the memory information when necessary, the most important thing is to use _ crtdumpmemoryleaks () when the program exits ();
If the program has more than one exit, we need to call this function in multiple places.
Furthermore, what if the program deletes the pointer in the class destructor? For example:

  1. # Include "stdafx. H"
  2. # Ifdef _ debug
  3. # Define debug_clientblock new (_ client_block, _ file __, _ line __)
  4. # Else
  5. # Define debug_clientblock
  6. # Endif
  7. # DEFINE _ crtdbg_map_alloc
  8. # Include <crtdbg. h>
  9. # Ifdef _ debug
  10. # Define new debug_clientblock
  11. # Endif
  12. Class Test
  13. {
  14. Public:
  15. Test () {_ p = new int ();}
  16. ~ Test () {Delete _ p ;}
  17. Int * _ P;
  18. };
  19. Int _ tmain (INT argc, _ tchar * argv [])
  20. {
  21. Int * P = new int ();
  22. Delete P;
  23. Test T;
  24. _ Crtdumpmemoryleaks ();
  25. Return 0;
  26. }

We can see that the Destructor are called only when the program exits, and the memory is clearly not leaked, but such a statement is still reported.
How can we improve it?Detect memory leakage Version 3:

  1. # Include "stdafx. H"
  2. # Ifdef _ debug
  3. # Define debug_clientblock new (_ client_block, _ file __, _ line __)
  4. # Else
  5. # Define debug_clientblock
  6. # Endif
  7. # DEFINE _ crtdbg_map_alloc
  8. # Include <crtdbg. h>
  9. # Ifdef _ debug
  10. # Define new debug_clientblock
  11. # Endif
  12. Class Test
  13. {
  14. Public:
  15. Test () {_ p = new int ();}
  16. ~ Test () {Delete _ p ;}
  17. Int * _ P;
  18. };
  19. Int _ tmain (INT argc, _ tchar * argv [])
  20. {
  21. _ Crtsetdbgflag (_ crtdbg_alloc_mem_df | _ crtdbg_leak_check_df );
  22. Int * P = new int ();
  23. Delete P;
  24. Test T;
  25. Return 0;
  26. }

_ Crtsetdbgflag (_ crtdbg_alloc_mem_df | _ crtdbg_leak_check_df );
This statement automatically calls _ crtdumpmemoryleaks when the program exits. _ Crtdbg_alloc_mem_df and _ crtdbg_leak_check_df must be set at the same time.
In this way, this version has achieved the same effect as MFC, but I think this is not enough, because we only output information in the output window, And the reminder to developers is not obvious, it is often missed, and many people will not repair the program's external performance even if they find that the memory is leaked. How can developers proactively fix memory leaks? I remember that I used to work with people to write a program. My function parameters are required and cannot be blank. However, when others always pass null values, there is no way to verify the function parameters, give him assert, so that when the program runs, the assert will always pop up, the pressure of debugging the program will be annoying, and other programmers will get bored, and the problem will be changed, and the input parameters will be correct. So I think we should let Programmers take the initiative to do one thing. First, let them feel that doing this thing can reduce their burden and make their work easier. Well, let's do the same. When the program exits, the program prompts out when the memory leak is detected.
ViewDetected Memory leakage version 4:

  1. # Include "stdafx. H"
  2. # Include <assert. h>
  3. # Ifdef _ debug
  4. # Define debug_clientblock new (_ client_block, _ file __, _ line __)
  5. # Else
  6. # Define debug_clientblock
  7. # Endif
  8. # DEFINE _ crtdbg_map_alloc
  9. # Include <crtdbg. h>
  10. # Ifdef _ debug
  11. # Define new debug_clientblock
  12. # Endif
  13. Void exit ()
  14. {
  15. Int I = _ crtdumpmemoryleaks ();
  16. Assert (I = 0 );
  17. }
  18. Int _ tmain (INT argc, _ tchar * argv [])
  19. {
  20. Atexit (exit );
  21. Int * P = new int ();
  22. Return 0;
  23. }

This version checks for Memory leakage when the program exits. If yes, a dialog box is displayed.
Atexit (exit); set to execute the exit () function when the program exits.
In the exit () function, if there is a memory leak, _ crtdumpmemoryleaks () will return a non-0 value and will be occupied by assert.

This version is ready for use. But we can also make some improvements, because to accurately detect all the memory leaks in the code, we need to # define…… in the code ...... Copy to all new files. It is impossible for every file to copy so much code, so we can extract it and put it in a file. For example, I put it in kdetectmemoryleak. h. The content of this file is as follows:

  1. # Pragma once
  2. # Ifdef _ debug
  3. # Define debug_clientblock new (_ client_block, _ file __, _ line __)
  4. # Else
  5. # Define debug_clientblock
  6. # Endif
  7. # DEFINE _ crtdbg_map_alloc
  8. # Include <stdlib. h>
  9. # Include <crtdbg. h>
  10. # Ifdef _ debug
  11. # Define new debug_clientblock
  12. # Endif

Then, kdetectmemoryleak. H is included in the general file of the project. For example, a project created with vs is included in stdafx. h. Or in a common. h file that I created myself, this file contains some common code that is used by almost all files.

Now, the detection of memory leaks has been completed, and he can find out which file is in the Code and which line has memory leaks. In the next article, we will talk about some actual problems, such as only knowing the memory leakage, but not the specific location of the Memory leakage, how can I use memory breakpoint and other technologies to locate memory leaks? In the end, I will explain how to avoid memory leaks from the code perspective.

This article comes from
Http://blog.csdn.net/zxcred

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.