Recently, I was writing a background service with a slightly larger amount of code, and there was a sign of Memory leakage during runtime. I found some code but still did not solve it completely.
It is said that Microsoft has its own memory detection tool. I use pure C ++. I tried it and wrote a tool to detect memory leakage in anger.
The principle is actually very simple, it is to reload the global new and delete, record the memory allocated and released. The usage is simple, as follows:
. EXE/DLL Project
1> Add. h and. cpp to the Project
2> Add # include to other CPP statements <. h>
3> Add the function at the beginning of the main function to call memexetraceinit ();
4> if it is used in DLL, memdlltraceinit () is added to processattech of dllmain;
Add a logout () call to processdetach.
5> secure multi-thread synchronization.
6> cross-platform security: multi-thread security is supported in windows. multi-thread security is not supported in Linux. You can simply modify the lock () and unlock () functions to implement multi-thread security in Linux.
I wrote a technical blog for the first time. I don't know how to upload attachments. I just need to paste the code below.
Memguard. cpp
# Include <iostream>
# Include <malloc. h>
# Include <map>
# Include <string>
# Ifdef Win32
# Include <windows. h>
# Else
# Include <pthread. h>
# Endif
Class _ fileinfo
{
Public:
_ Fileinfo ();
STD: String file;
Int line;
};
# Ifdef Win32
Static handle _ hmutex = createmutex (null, false, null );
# Else
// Define Linux mutex
# Endif
Void lock () // multithreading lock function
{
# Ifdef Win32
Waitforsingleobject (_ hmutex, infinite );
# Else
// Linux lock
# Endif
}
Void unlock ()
{
# Ifdef Win32
Releasemutex (_ hmutex );
# Else
// Linux lock
# Endif
}
Using namespace STD;
Static bool _ initialized = false;
Static Map <long ,__ fileinfo >__ memtrace;
_ Fileinfo ::__ fileinfo ()
{
This-> line =-1;
}
Void * operator new [] (size_t size, const char * file, int line)
{
Void * P = NULL;
If (size = 0)
{
Size = 1;
}
While (1 ){
P = malloc (size );
If (P! = NULL)
{
Break;
}
// The allocation fails. Find the processing function for the current error.
New_handler globalhandler = set_new_handler (0 );
Set_new_handler (globalhandler );
If (globalhandler) (* globalhandler )();
Else throw STD: bad_alloc ();
}
If (P! = NULL & _ initialized = true)
{
_ Fileinfo Info;
Lock ();
Info. File = string (File );
Info. Line = line;
_ Memtrace. insert (make_pair (long) P, Info ));
Unlock ();
}
Return P;
}
Void * operator new (size_t size, const char * file, int line)
{
Void * P = NULL;
If (size = 0)
{
Size = 1;
}
While (1 ){
P = malloc (size );
If (P! = NULL)
{
Break;
}
// The allocation fails. Find the processing function for the current error.
New_handler globalhandler = set_new_handler (0 );
Set_new_handler (globalhandler );
If (globalhandler) (* globalhandler )();
Else throw STD: bad_alloc ();
}
If (P! = NULL & _ initialized = true)
{
_ Fileinfo Info;
Lock ();
Info. File = string (File );
Info. Line = line;
_ Memtrace. insert (make_pair (long) P, Info ));
Unlock ();
}
Return P;
}
Void operator Delete (void * P)
{
If (_ initialized = true)
{
Lock ();
_ Memtrace. Erase (long (p ));
Unlock ();
}
Free (P );
}
Void operator Delete [] (void * P)
{
If (_ initialized = true)
{
Lock ();
_ Memtrace. Erase (long (p ));
Unlock ();
}
// Free (P );
Free (P );
}
Void logout ()
{
File * fp = fopen ("memguard. log", "W + ");
If (FP = NULL)
{
Return;
}
Fprintf (FP, "memguard output:/N ");
For (Map <long ,__ fileinfo >:: iterator ITER =__ memtrace. Begin (); iter! = _ Memtrace. End (); ITER ++)
{
Fprintf (FP, "Memory leakage:/N ");
Fprintf (FP, "ADDR: 0x % 08x/N", ITER-> first );
Fprintf (FP, "file: % s/n", ITER-> second. file. c_str ());
Fprintf (FP, "line: % d/N", ITER-> second. line );
}
Fclose (FP );
Closehandle (_ hmutex );
Return;
}
Void memexetraceinit ()
{
Atexit (logout );
_ Hmutex = createmutex (null, false, null );
_ Initialized = true;
}
Void memdlltraceinit ()
{
_ Hmutex = createmutex (null, false, null );
_ Initialized = true;
}
Void memdllprocessdetach ()
{
Logout ();
}
# Include <iostream> # include <malloc. h> # include <map> # include <string> # ifdef Win32 # include <windows. h> # else # include <pthread. h ># endifclass _ fileinfo {public :__ fileinfo (); STD: String file; int line ;};# ifdef win32static handle _ hmutex; # else // defines Linux mutex # endifvoid lock () // multithreading lock function {# ifdef win32waitforsingleobject (_ hmutex, infinite ); # else // Linux lock # endif} void unlock () {# ifdef win32releasemutex (_ hmutex );# Else // Linux lock # endif} using namespace STD; static bool _ initialized = false; static Map <long ,__ fileinfo >__ memtrace ;__ fileinfo ::__ fileinfo () {This-> line =-1;} void * operator new [] (size_t size, const char * file, int line) {void * P = NULL; if (size = 0) {size = 1;} while (1) {P = malloc (size); If (P! = NULL) {break;} // allocation failed. Find the current error handler new_handler globalhandler = set_new_handler (0); set_new_handler (globalhandler); If (globalhandler) (* globalhandler) (); else throw STD: bad_alloc ();} If (P! = NULL & _ initialized = true) {__ fileinfo Info; lock (); info. file = string (File); info. line = line ;__ memtrace. insert (make_pair (long) P, Info); unlock ();} return P;} void * operator new (size_t size, const char * file, int line) {void * P = NULL; If (size = 0) {size = 1;} while (1) {P = malloc (size); If (P! = NULL) {break;} // allocation failed. Find the current error handler new_handler globalhandler = set_new_handler (0); set_new_handler (globalhandler); If (globalhandler) (* globalhandler) (); else throw STD: bad_alloc ();} If (P! = NULL & _ initialized = true) {__ fileinfo Info; lock (); info. file = string (File); info. line = line ;__ memtrace. insert (make_pair (long) P, Info); unlock ();} return P;} void operator Delete (void * P) {If (_ initialized = true) {lock () ;__ memtrace. erase (long (p); unlock ();} Free (p);} void operator Delete [] (void * P) {If (_ initialized = true) {lock () ;__ memtrace. erase (long (p); unlock () ;}// free (p);} void log Out () {file * fp = fopen ("memguard. log "," W + "); If (FP = NULL) {return;} fprintf (FP," memguard output:/N "); For (Map <long, __fileinfo>: iterator iter = _ memtrace. begin (); iter! = _ Memtrace. end (); ITER ++) {fprintf (FP, "Memory leakage:/N"); fprintf (FP, "ADDR: 0x % 08x/N ", ITER-> first); fprintf (FP, "file: % s/n", ITER-> second. file. c_str (); fprintf (FP, "line: % d/N", ITER-> second. line);} fclose (FP); closehandle (_ hmutex); return;} void memexetraceinit () {atexit (logout); _ hmutex = createmutex (null, false, null); _ initialized = true;} void memdlltraceinit () {__ hmutex = createmutex (null, false, null) ;__ initialized = true;} void memdllprocessdetach () {logout ();} memguard. h # ifndef _ mem_guard _ # DEFINE _ mem_guard _ # include <iostream> # include <stdio. h> void * operator new (size_t size, const char * file, int line); void * operator new [] (size_t size, const char * file, int line ); void operator Delete (void * P); void operator Delete [] (void * P); void memexetraceinit (); void memdlltraceinit (); void memdllprocessdetach (); # define new (_ file __,__ line _) # endifv