/* * MemDebug.cpp * * Created on: Apr 28, 2010 * Author: crueger */ #include #include using namespace std; namespace Memory { struct entry_t { struct info_t { char file[256]; int line; size_t nbytes; bool isUsed; void *location; } info; bool isIgnored; char checksum; entry_t *prev; entry_t *next; }; entry_t *begin=0; entry_t *end=0; size_t state = 0; size_t max = 0; const int alignment = 8; inline char calcChecksum(entry_t::info_t *info){ char *buffer = (char*)info; char checksum =0; for(size_t i=0;inext){ cout << "\nChunk of " << pos->info.nbytes << " bytes" << " still available" << endl; cout << "Chunk reserved at: " << pos->info.file << ":" << pos->info.line << endl; } } void deleteEntry(entry_t *entry){ if(entry->isIgnored) return; if(entry->prev){ entry->prev->next = entry->next; } else{ begin = entry->next; } if(entry->next){ entry->next->prev = entry->prev; } else{ end = entry->prev; } entry->isIgnored = true; Memory::state -= entry->info.nbytes; } void _ignore(void *ptr){ static const size_t entrySpace = Memory::doAlign(sizeof(Memory::entry_t)); entry_t *entry = (Memory::entry_t*)((char*)ptr-entrySpace); deleteEntry(entry); } } void *operator new(size_t nbytes,const char* file, int line) throw(std::bad_alloc) { if(!nbytes) { nbytes = 1; } static const size_t entrySpace = Memory::doAlign(sizeof(Memory::entry_t)); void *res; if(!(res=malloc(entrySpace + nbytes))){ throw std::bad_alloc(); } Memory::state += nbytes; if(Memory::state>Memory::max){ Memory::max = Memory::state; } Memory::entry_t *entry = (Memory::entry_t*) res; entry->info.nbytes = nbytes; entry->info.isUsed = true; strncpy(entry->info.file,file,256); entry->info.file[255] = '\0'; entry->info.line=line; entry->info.location = (char*)res + entrySpace; entry->next=0; entry->prev=Memory::end; if(!Memory::begin){ Memory::begin=entry; } else { Memory::end->next=entry; } Memory::end=entry; entry->checksum = Memory::calcChecksum(&entry->info); entry->isIgnored = false; return entry->info.location; } void *operator new(size_t nbytes) throw(std::bad_alloc) { return operator new(nbytes,"Unknown",0); } void *operator new[] (size_t nbytes,const char* file, int line) throw(std::bad_alloc) { return operator new(nbytes,file,line); } void *operator new[] (size_t nbytes) throw(std::bad_alloc) { return operator new[] (nbytes,"Unknown",0); } void operator delete(void *ptr) throw() { static const size_t entrySpace = Memory::doAlign(sizeof(Memory::entry_t)); Memory::entry_t *entry = (Memory::entry_t*)((char*)ptr-entrySpace); if(Memory::calcChecksum(&entry->info)!=entry->checksum){ cout << "Possible memory corruption detected!" << endl; cout << "Trying to recover allocation information..." << endl; cout << "Memory was allocated at " << entry->info.file << ":" << entry->info.line << endl; terminate(); } entry->info.isUsed = false; Memory::deleteEntry(entry); free((char*)ptr-entrySpace); } void operator delete(void *ptr,const char*, int) throw() { operator delete(ptr); } void operator delete[](void *ptr){ operator delete(ptr); } void operator delete[](void *ptr,const char*, int) throw(){ operator delete(ptr); }