#ifdef DEBUG_MEMORY_LEAK #include "Common/include/Message.h" #include #include #include #include #include using namespace std; using namespace morpheo; #undef new // Global flags set by macros in MemCheck.h bool traceFlag = false; bool activeFlag = false; namespace { // Memory map entry type struct Info { // void* ptr; const char* file; long line; size_t size; }; bool Info_lt(std::pair a, std::pair b) { return a.second.size < b.second.size; } // Memory map data typedef map memMap_t; typedef map::iterator memMap_it; memMap_t memMap; // Searches the map for an address memMap_it findPtr(void* p) { return memMap.find(p); } void delPtr(void* p) { memMap_it it = findPtr(p); assert(it != memMap.end()); // Remove pointer from map memMap.erase(it); } // Dummy type for static destructor struct Sentinel { ~Sentinel() { size_t size = memMap.size(); if(size > 0) { size_t size_sum = 0; msgWarning("Leaked memory at:\n"); for (memMap_it it=memMap.begin(); it!=memMap.end(); ++it) { size_t s = it->second.size; size_sum += s; msgWarning("\t%p : %u bytes (file: %s, line %ld)\n", it->first, s, it->second.file, it->second.line); } msgWarning("Total : %u bytes on %d localisations\n",size_sum, size); uint32_t nb_top = (size>10)?10:size; msgWarning("Top %d of leaked memory\n",nb_top); for (uint32_t i=0; isecond.size, max->second.file, max->second.line); memMap.erase(max); } } else msgInformation("No user memory leaks!\n"); } }; // Static dummy object Sentinel s; } // End anonymous namespace // Overload scalar new void* operator new(size_t size, const char* file, long line) { void* p = malloc(size); if(activeFlag) { Info info; info.file = file; info.line = line; info.size = size; memMap[p] = info; } if(traceFlag) { msgInformation("Allocated %u bytes at address %p (file: %s, line: %ld)\n", size, p, file, line); } return p; } // Overload array new void* operator new[](size_t size, const char* file, long line) { return operator new(size, file, line); } // Override scalar delete void operator delete(void* p) { bool can_free = true; if (activeFlag) { memMap_it it = findPtr(p); if (it != memMap.end()) { // this pointer is previously allocated delPtr(p); } else { // this pointer is not previously allocated can_free = false; msgError("Attempt to delete unknown pointer: %p\n", p); } } if (can_free) { if(traceFlag) msgInformation("Deleted memory at address %p\n", p); free(p); } } // Override array delete void operator delete[](void* p) { operator delete(p); } #endif // DEBUG_MEMORY_LEAK