Detection of memory leaks in C + +

Source: Internet
Author: User
Tags assert
First we need to know if the program has a memory leak, and then locate exactly which line of code has a memory leak so that it can be repaired.

The simplest way of course is to rely on professional detection tools, more famous such as Boundscheck, the function is very powerful, I believe that the development of C + + people can not do without it. It is also not
First we need to know if the program has a memory leak, and then locate exactly which line of code has a memory leak so that it can be repaired.

The simplest way of course is to rely on professional detection tools, more famous such as Boundscheck, the function is very powerful, I believe that the development of C + + people can not do without it. In addition to not using any tools, but to implement the monitoring of memory leaks, in the following two scenarios:

I. Detecting a memory leak in MFC

If it is using MFC's program, it is very simple. The default is a memory leak detection feature.

We used VS2005 to generate an MFC dialog box program, found that he can automatically detect memory leaks. We don't have to do any special things. Careful observation, found in each CPP file, there is the following code:
#ifdef _DEBUG
#define NEW Debug_new
#endif

DEBUG_NEW This macro is defined in the Afx.h file, which helps us locate the memory leak.

If there is no deletion after allocating memory in the CPP file containing the above code, the VisualStudio Output window will display the following information when the program is stopped:
Detected memory leaks!
Dumping objects
D:\code\mfctest\mfctest.cpp: {157} normal block at 0x003af170, 4 bytes long.
Data: < > 00 00 00 00
Object dump complete.

Double-clicking the bold line in the Output window will open the file and navigate to the row, and it is easy to see where the memory leak occurred.

Two Detecting program memory leaks in pure C + +

I tried the Win32 Console application and Win32 project projects that were built with VisualStudio, and the results were not able to detect a memory leak.

The following step-by-step procedure to set up a mechanism for memory leak detection.

First, we need to know that the debug version of the C runtime provides a number of detection features that make it easier for us to debug the program. There's a special section on MSDN that says this, called Debug Routines, and it's recommended that you look at what's inside.

We'll use a few of the functions that are important inside. One of the most important is _CrtDumpMemoryLeaks; see the MSDN Help yourself. With this function, you need to include the header file Crtdbg.h

This function is only available in the debug version, and _CrtDumpMemoryLeaks displays the memory leak information in the Output window when the program is run under the debugger. Write the code to test it, as follows:

Detect a memory leak version one:
#include "stdafx.h"
#include <crtdbg.h>
int _tmain (int argc, _tchar* argv[])
{
int* p = new int;
_CrtDumpMemoryLeaks;
return 0;
}

After running, in the Output window, the following information is displayed:
Detected memory leaks!
Dumping objects
{0x003aa770} normal block at 4 bytes long.
Data: < > 00 00 00 00
Object dump complete.

But this is just to tell us that the program has a memory leak, in the end where the leakage of a glance does not come out AH.

Look at our detection of memory leaks version two:

#include "stdafx.h"
#ifdef _DEBUG
#define Debug_clientblock New (_client_block, __file__, __line__)
#else
#define Debug_clientblock
#endif
#define _crtdbg_map_alloc
#include <crtdbg.h>
#ifdef _DEBUG
#define NEW Debug_clientblock
#endif
int _tmain (int argc, _tchar* argv[])
{
int* p = new int;
_CrtDumpMemoryLeaks;
return 0;
}

The program defines a few macros that are replaced by a macro with new in the debug version, and the new update records the file name and line of code when you call new. After running, you can see the following results:

Detected memory leaks!
Dumping objects
D:\code\consoletest\consoletest.cpp: {The client block at 0x003a38b0, subtype 0, 4 bytes long.
Data: < > 00 00 00 00
Object dump complete.

Oh, and MFC program has the same effect, but wait. Let's look at the following code:

int _tmain (int argc, _tchar* argv[])
{
int* p = new int;
_CrtDumpMemoryLeaks;
Delete p;
return 0;
}

After running it can be found that we have removed the pointer, but it still reported a memory leak. So it can be imagined that every call to new, the inside of the program will record the call, similar to the number of records, if the delete, then it is removed from the array, and _CrtDumpMemoryLeaks is the current state of the array to print out.

Therefore, in addition to the need to dump out of memory information, the most important thing is to quit the program when you need to drop the _crtdumpmemoryleaks;

If the program has more than one exit, then we need to call the function in many places.

Further, what if the program deletes the pointer in the destructor of the class? For example:

#include "stdafx.h"
#ifdef _DEBUG
#define Debug_clientblock New (_client_block, __file__, __line__)
#else
#define Debug_clientblock
#endif
#define _crtdbg_map_alloc
#include <crtdbg.h>
#ifdef _DEBUG
#define NEW Debug_clientblock
#endif
Class Test
{
Public
Test {_p = new int;}
~test {delete _p;}
int* _p;
};
int _tmain (int argc, _tchar* argv[])
{
int* p = new int;
Delete p;
Test T;
_CrtDumpMemoryLeaks;
return 0;
}

You can see the destructor is called when the program exits, obviously there is no memory leak, but this writing is still reported.

How to improve it, look at detecting memory leaks version three:

#include "stdafx.h"
#ifdef _DEBUG
#define Debug_clientblock New (_client_block, __file__, __line__)
#else
#define Debug_clientblock
#endif
#define _crtdbg_map_alloc
#include <crtdbg.h>
#ifdef _DEBUG
#define NEW Debug_clientblock
#endif
Class Test
{
Public
Test {_p = new int;}
~test {delete _p;}
int* _p;
};
int _tmain (int argc, _tchar* argv[])
{
_CrtSetDbgFlag (_CRTDBG_ALLOC_MEM_DF | _crtdbg_leak_check_df);
int* p = new int;
Delete p;
Test T;
return 0;
}

_CrtSetDbgFlag (_CRTDBG_ALLOC_MEM_DF | _crtdbg_leak_check_df); This statement automatically calls _CrtDumpMemoryLeaks when the program exits. Both _CRTDBG_ALLOC_MEM_DF and _CRTDBG_LEAK_CHECK_DF must be set.

In this way, the version has reached the same effect as MFC, but I think the light is not enough, because we are only in the Output window to export information, the developer's reminders are not obvious, often be omitted, and many people even found a memory leak, but not good repair, will not seriously affect the external performance of the program, are not fixed. How can developers proactively fix the problem of memory leaks? Remember once with people to write the program, my function parameters have requirements, can not be empty, but others always pass null value, no way, had to start in the function to verify the function parameters, give him assert live, so that the program is always constantly pop up assert, debugging program that annoying pressure, and finally other programmers bored, The problem is changed, the input parameters are correct. So I think we have to let the programmer take the initiative to do something, first of all, let him feel that doing this is to reduce their burden, so that their work relaxed. Well, then we also, when the program exits, detected a memory leak let the program prompt out.

See detecting memory leaks version four:

#include "stdafx.h"
#include <assert.h>
#ifdef _DEBUG
#define Debug_clientblock New (_client_block, __file__, __line__)
#else
#define Debug_clientblock
#endif
#define _crtdbg_map_alloc
#include <crtdbg.h>
#ifdef _DEBUG
#define NEW Debug_clientblock
#endif
void Exit
{
int i = _CrtDumpMemoryLeaks;
assert (i = = 0);
}
int _tmain (int argc, _tchar* argv[])
{
Atexit (Exit);
int* p = new int;
return 0;
}

This version checks for memory leaks when the program exits, and if present, pops up a prompt dialog box.

Atexit (exit); Sets the Exit function to execute when the program exits. In the Exit function, if there is a memory leak, _CrtDumpMemoryLeaks will return a value other than 0 and it will be assert.

This version has reached the point where it can be used. But we can also make some improvements, because it is really necessary to accurately detect all the memory leaks in the code and need to put a # define in the code ... Copy to all files that use new. It is not possible to copy so much code per file, so we can extract it and put it in a file, for example, I put it in KDetectMemoryLeak.h, the file reads:

#pragma once
#ifdef _DEBUG
#define Debug_clientblock New (_client_block, __file__, __line__)
#else
#define Debug_clientblock
#endif
#define _crtdbg_map_alloc
#include <stdlib.h>
#include <crtdbg.h>
#ifdef _DEBUG
#define NEW Debug_clientblock
#endif

The KDetectMemoryLeak.h is then included in the project's generic file, such as a project built with VS, which is included in the stdafx.h. Or I built it myself. A Common.h file that contains some common code that all basic files will use.

  • 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.