First we need to know whether the program has a memory leak, and then locate which line of code has the memory leak, so that we can fix it.
The easiest way is of course to use professional detection tools, such as BoundsCheck, which is well-known and very powerful. I believe that no one who develops C++ can do without it. In addition, it is not necessary. First, we need to know whether the program has a memory leak, and then locate which line of code has the memory leak, so that it can be repaired.
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
Detected memory leaks!
Dumping objects ->
d:codemfctestmfctest .cpp(80) : {157} normal block at 0x003AF170, 4 bytes long.
Data: < > 00 00 00 00
Object dump complete.
#include "stdafx.h"
#include
int _tmain(int argc, _TCHAR* argv[])
{
int* p = new int;
_CrtDumpMemoryLeaks;
return 0;
}
Detected memory leaks!
Dumping objects ->
{112} normal block at 0x003AA770 , 4 bytes long.
Data: < > 00 00 00 00
Object dump complete.
#ifdef _DEBUG
#define DEBUG_CLIENTBLOCK new( _CLIENT_BLOCK, __FILE__, __LINE__)
#else
#define DEBUG_CLIENTBLOCK
#endif
#define _CRTDBG_MAP_ALLOC
#include
#ifdef _DEBUG
#define new DEBUG_CLIENTBLOCK
#endif
int _tmain(int argc, _TCHAR* argv[])
{
int* p = new int;
_CrtDumpMemoryLeaks;
return 0 ;
}
Dumping objects ->
d:codeconsoletestconsoletest.cpp(21) : {112} client block at 0x003A38B0, subtype 0, 4 bytes long.
Data: < > 00 00 00 00
Object dump complete.
{
int* p = new int;
_CrtDumpMemoryLeaks;
delete p;
return 0;
}
#include "stdafx.h"
#ifdef _DEBUG
#define DEBUG_CLIENTBLOCK new( _CLIENT_BLOCK, __FILE__, __LINE__)
#else
#define DEBUG_CLIENTBLOCK
#endif
#define _CRTDBG_MAP_ALLOC
#include
#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 that the destructor is only called when the program exits, obviously not Memory leak, but this way of writing is still reported.
How to improve, see memory leak detection version 3:
#include "stdafx.h"
#ifdef _DEBUG
#define DEBUG_CLIENTBLOCK new( _CLIENT_BLOCK, __FILE__, __LINE__)
#else
#define DEBUG_CLIENTBLOCK
#endif
# Define_CRTDBG_MAP_ALLOC
#Include & lt; CRTDBG.H & GT;
#Ifdef _debug
#define New Debug_ClientBlock
#Endifehclass test
{
Public: PTest {_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. _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 , are often missed, and even if many people find a memory leak, it is not easy to repair, and it will not seriously affect the external performance of the program, so they will not repair it. How can developers proactively fix memory leaks? I remember that I once collaborated with someone to write a program. My function parameters had requirements and could not be empty, but others always passed null values. I had no choice but to verify the function parameters at the beginning of the function and assert them. In this way, when the program was running, it would always The assert kept popping up, which made debugging the program very stressful. Finally, other programmers got annoyed, so they fixed the problem and entered the parameters correctly. So I think that if we want programmers to take the initiative to do something, we must first make them feel that doing this can reduce their own burden and make their work easier. Haha, let's do the same. When the program exits, if a memory leak is detected, the program will prompt it.
See memory leak detection version 4:
#include "stdafx.h"
#include#ifdef _DEBUG
#define DEBUG_CLIENTBLOCK new( _CLIENT_BLOCK, __FILE__, __LINE__)
#else
#define DEBUG_ CLIENTBLOCK
#endif
#define _CRTDBG_MAP_ALLOC
#include
#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 will check for memory leaks when the program exits, if it exists A prompt dialog box will pop up.
atexit(Exit); sets the Exit function to be executed when the program exits. In the Exit function, if there is a memory leak, _CrtDumpMemoryLeaks will return a non-0 value and it will be asserted.
This version is ready for use. But we can still make some improvements, because if we really want to accurately detect all memory leaks in the code, we need to copy the #define... in the code to all files using new. It is impossible to copy so much code for each file, so we can extract it and put it in a file. For example, I put it in KDetectMemoryLeak.h. The content of the file is as follows:
#pragma once
#ifdef _DEBUG #define DEBUG_CLIENTBLOCK new( _CLIENT_BLOCK, __FILE__, __LINE__)
#else
#define DEBUG_CLIENTBLOCK
#endif
#define _CRTDBG_MAP_ALLOC
#include
#include
#define new DEBUG_CLIENTBLOCK
#endif
Then include KDetectMemoryLeak.h in the common file of the project. For example, for projects built with VS, include it in stdafx.h. Or I created a Common.h file myself, which contains some common code that is used by basically all files.