www.pudn.com > zfxcengine-0.1.0.zip > ceMemManager.cpp
// $Id: ceMemManager.cpp,v 1.8 2005/09/03 14:24:14 kimmi Exp $ #include#include #include
#include #include #include using std::endl; using std::cout; using std::flush; #ifdef _DEBUG typedef struct { intptr_t uiAddress; size_t uiSize; // XXX: 128 is too short. For filename, use MAXPATHLEN. char Filename[128]; char Functionname[128]; unsigned int uiLine; } sPageInfo; typedef std::list PageList; static PageList* ListOfPages=NULL; void PrintUnfreed(void); void AddPage(intptr_t uiAddress, size_t uiSize, const char* filename, const char* functionname, unsigned int uiLine) { static unsigned char atExit=0; if(!atExit) { atexit(PrintUnfreed); atExit=1; } sPageInfo* Page=NULL; if(!ListOfPages) ListOfPages = new(PageList); // with the standard braces we force the compiler to use the standard new Page = new(sPageInfo); Page->uiAddress = uiAddress; strncpy(&Page->Filename[0], &filename[0], 128); strncpy(&Page->Functionname[0], &functionname[0], 128); Page->uiLine = uiLine; Page->uiSize = uiSize; ListOfPages->insert(ListOfPages->begin(), Page); } void RemovePage(intptr_t uiAddress) { if(!ListOfPages || ListOfPages->size() == 0) return; for(PageList::iterator it = ListOfPages->begin(); it != ListOfPages->end(); it++) { // check if the given address matches this page if((*it)->uiAddress == uiAddress) { ListOfPages->remove((*it)); break; } } } void PrintUnfreed(void) { if (!ListOfPages || ListOfPages->size() == 0) { cout << "All Memory has been deleted!" << endl; return; } std::string Filename = "memorylog.txt"; FILE* File=NULL; if(Filename.length() ) { File = fopen(Filename.c_str(), "w"); if(!File) cout << "Warning: Couldnt open log file" << endl; } unsigned int c = 0; double MemSum = 0; std::vector ListOfUnfreedMemory; for(PageList::iterator it = ListOfPages->begin(); it != ListOfPages->end(); it++,c++) { cout << "Page " << c << ": " << endl; cout << "\tFile: " << (*it)->Filename << endl; cout << "\tFunction: " << (*it)->Functionname << endl; cout << "\tLine: " << (*it)->uiLine << endl; cout << "\tSize: " << (*it)->uiSize << endl; cout << "\tAddress: " << (*it)->uiAddress << endl << endl; if(File) { fprintf(File, "Page %i: \n", c);fflush(File); fprintf(File, "\tFile: %s\n", (*it)->Filename);fflush(File); fprintf(File, "\tFunction: %s\n", (*it)->Functionname); fflush(File); fprintf(File, "\tLine: %i\n", (*it)->uiLine); fflush(File); fprintf(File, "\tSize: %i\n", (*it)->uiSize); fflush(File); fprintf(File, "\tAddress: %i\n", (*it)->uiAddress); fflush(File); } ListOfUnfreedMemory.push_back((*it)->uiAddress); // calculate overall memory, that was not freed in Megabytes MemSum += ( (*it)->uiSize / (1024*1024) ); } cout << "Overall Memory: " << MemSum << "MiB" << endl; cout << "I will free the existing memory now!" << endl; if(File) { fprintf(File, "Overall Memory: %fMiB\n", MemSum);fflush(File); } for (std::vector ::iterator it = ListOfUnfreedMemory.begin(); it != ListOfUnfreedMemory.end(); it++) { RemovePage(*it); free( (void*) (*it)); } fclose(File); } void* operator new(size_t uiSize, const char* filename, const char* functionname, unsigned int uiLine) { void* mem = (void*) calloc(uiSize, 1); AddPage((intptr_t) mem, uiSize, filename, functionname, uiLine); return mem; } void* operator new[](size_t uiSize, const char* filename, const char* functionname, unsigned int uiLine) { void* mem = (void*) calloc(uiSize, 1); AddPage((intptr_t) mem, uiSize, filename, functionname, uiLine); return mem; } void operator delete(void *p) throw () { if(p != NULL) { RemovePage((intptr_t) p); free(p); p = NULL; } } void operator delete[](void *p) throw () { if(p != NULL) { RemovePage((intptr_t) p); free(p); p = NULL; } } #else void PrintUnfreed(void) { cout << "No known unfreed memory!" << endl; } #endif