I'm trying to implement a crude memory tracking, following this source:
http://www.chrisculy.com/writings/Programmatic_Memory_Leak_Detection_in_C++.pdf
However, most things works fine (apart from delete crashing) except that I can't macro the new keyword. I'v been searching far and wide for any answers on how to do it. But I haven't found anything.
I'm using Visual Studio 2012, here is the source:
Rememrall.h
#ifdef _DEBUG
void* operator new(size_t size, const char* file, unsigned int line);
void operator delete(void* memory);
#undef new
#define new new(__FILE__, __LINE__)
#endif
void reportMemoryStatus();
Remembrall.cpp
#ifdef _DEBUG
#include "Remembrall.h"
#include "Logger.h"
#include <cstring>
#include <cstdlib>
#include <list>
#include <iostream>
static std::string stripped_path( const char* str )
{
std::string path = str;
return path.substr(path.find_last_of('\\')+1, path.size()-1);
}
struct MemoryRecord
{
const char* file;
unsigned int line;
unsigned int size;
unsigned long address;
};
static std::list< MemoryRecord > memoryArchive;
void* operator new(size_t size, const char* file, unsigned int line)
{
void* memory = malloc(size);
MemoryRecord record;
record.file = file;
record.line = line;
record.size = size;
record.address = (unsigned long) memory;
memoryArchive.push_back(record);
return memory;
}
void operator delete(void* memory)
{
/*
auto it = memoryArchive.begin();
auto end = memoryArchive.end();
while(it != end)
{
if( (*it).address == ( unsigned long ) memory )
{
memoryArchive.erase(it);
break;
}
it++;
}
*/
free(memory);
}
void reportMemoryStatus()
{
auto it = memoryArchive.begin();
std::string info = "";
while( !memoryArchive.empty() )
{
info = "[MEMLEAK]\tFile: ";
info += stripped_path((*it).file);
info += "\tLine: ";
info += std::to_string((*it).line);
info += "\tAddress: ";
info += std::to_string((*it).address);
info += "\tSize: ";
info += std::to_string((*it).size);
std::cout << info << std::endl;
db::logger.write( info, db::outs::error, true );
memoryArchive.erase(it);
it = memoryArchive.begin();
}
db::logger.panic();
}
#else
void reportMemoryStatus() {}
#endif
EDIT
I found a solution, making a new header, include the Remembrall-header then AFTER that add the new macro. It feels kind of hackish, is this really the only way?