Skip to content

Instantly share code, notes, and snippets.

@mandyedi
Created December 12, 2015 10:09
Show Gist options
  • Save mandyedi/1273180442e5e01dac4d to your computer and use it in GitHub Desktop.
Save mandyedi/1273180442e5e01dac4d to your computer and use it in GitHub Desktop.
c++ memory leak (not thread safe)
// 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