Created
December 12, 2015 10:09
-
-
Save mandyedi/1273180442e5e01dac4d to your computer and use it in GitHub Desktop.
c++ memory leak (not thread safe)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// http://www.flipcode.com/archives/How_To_Find_Memory_Leaks.shtml | |
// http://en.cppreference.com/w/cpp/memory/new/operator_new | |
// http://en.cppreference.com/w/cpp/memory/new/operator_delete | |
#ifndef DETECT_MEMORY_LEAK_H | |
#define DETECT_MEMORY_LEAK_H | |
#include <cstdlib> | |
#include <cstring> | |
#include <iostream> | |
#include <list> | |
#define DETECT_MEMORY_LEAK | |
#ifdef DETECT_MEMORY_LEAK | |
void AddTrack( unsigned int addr, size_t asize, const char *fname, unsigned int lnum ); | |
void RemoveTrack( size_t addr ); | |
inline void* AllocateMemory( size_t size, const char *file, int line ) | |
{ | |
void *ptr = (void *)malloc( size ); | |
AddTrack( (unsigned int)ptr, size, file, line ); | |
return ptr; | |
} | |
inline void* __cdecl operator new( size_t size, const char *file, int line ) | |
{ | |
return AllocateMemory( size, file, line ); | |
}; | |
inline void * __cdecl operator new[]( size_t size, const char *file, int line ) | |
{ | |
return AllocateMemory( size, file, line ); | |
} | |
inline void FreeMemory( void *p ) | |
{ | |
RemoveTrack( (unsigned int)p ); | |
free( p ); | |
} | |
inline void __cdecl operator delete( void *p ) | |
{ | |
return FreeMemory( p ); | |
}; | |
inline void __cdecl operator delete[]( void *p ) | |
{ | |
return FreeMemory( p ); | |
}; | |
// TODO: support multiple threads | |
struct AllocInfo | |
{ | |
unsigned int address; | |
size_t size; | |
char file[64]; | |
unsigned int line; | |
}; | |
typedef std::list<AllocInfo*> AllocList; | |
AllocList *allocList; | |
void AddTrack( unsigned int addr, size_t asize, const char *fname, unsigned int lnum ) | |
{ | |
AllocInfo *info; | |
if( !allocList ) | |
{ | |
allocList = new( AllocList ); | |
} | |
info = new( AllocInfo ); | |
info->address = addr; | |
strncpy(info->file, fname, 63); | |
info->line = lnum; | |
info->size = asize; | |
allocList->insert(allocList->begin(), info); | |
}; | |
void RemoveTrack( size_t addr ) | |
{ | |
if( !allocList ) | |
{ | |
return; | |
} | |
AllocList::iterator i; | |
for( i = allocList->begin(); i != allocList->end(); ++i ) | |
{ | |
if( (*i)->address == addr ) | |
{ | |
allocList->remove( (*i) ); | |
break; | |
} | |
} | |
}; | |
void DumpUnfreed() | |
{ | |
if( !allocList ) | |
{ | |
return; | |
} | |
unsigned int totalSize = 0; | |
char buf[1024]; | |
AllocList::iterator i; | |
for(i = allocList->begin(); i != allocList->end(); i++) | |
{ | |
sprintf( buf, "%-50s: LINE %d, ADDRESS 0x%x %d bytes unfreed\n", (*i)->file, (*i)->line, (*i)->address, (*i)->size ); | |
std::cout << buf; | |
totalSize += (*i)->size; | |
} | |
sprintf(buf, "-----------------------------------------------------------\n"); | |
std::cout << buf; | |
sprintf(buf, "Total Unfreed: %d bytes\n", totalSize); | |
std::cout << buf; | |
}; | |
#define DEBUG_NEW new(__FILE__, __LINE__) | |
#else | |
#define DEBUG_NEW new | |
#endif // DETECT_MEMORY_LEAK | |
#define new DEBUG_NEW | |
#endif // DETECT_MEMORY_LEAK_H |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment