/////////////////////////////////////////////////////////////////////// // memCheck.cpp - utility to check heap memory allocations // // ver 1.0 // // // // Language: Visual C++, ver 6.0 // // Platform: Dell XPs1000r, Windows 2000 Professional // // Application: ImageTrek Project - CASE Center // // Author: Jim Fawcett, CST 2-187, Syracuse Univ. // // jfawcett@twcny.rr.com, (315) 443-3948 // /////////////////////////////////////////////////////////////////////// #include #include #include #include "memCheck.h" using namespace std; //----< constructor taking name, has default = "" >-------------------- memCheck::memCheck(const char *name) { if(name) { strncpy(objName,name,MAX); objName[MAX] = '\0'; } else objName[0] = '\0'; _CrtMemCheckpoint(&memState); } //----< constructor taking a Win32 API _CrtMemState struct >----------- memCheck::memCheck(const _CrtMemState &ms) : memState(ms) { objName[0] = '\0'; } //----< destructor >--------------------------------------------------- memCheck::~memCheck() { } //----< supply object with a name >------------------------------------ void memCheck::name(const char *Name) { strncpy(objName,Name,MAX); objName[MAX] = '\0'; } // //----< read object's name >------------------------------------------- const char* memCheck::name() const { return objName; } //----< refresh heap state data >-------------------------------------- void memCheck::refresh() { _CrtMemCheckpoint(&memState); } //----< test for equality of heap state >------------------------------ bool memCheck::operator==(const memCheck &d) { _CrtMemState temp; return (!_CrtMemDifference(&temp,&d.memState,&memState)); } //----< display heap state on stdout >--------------------------------- void memCheck::state() { cout << "\n " << objName << " - heap state:"; cout << "\n ============================================" << "\n " << setw(4) << memState.lCounts[0] << " Free blocks holding " << setw(11) << memState.lSizes[0] << " bytes" << "\n " << setw(4) << memState.lCounts[1] << " Normal blocks holding " << setw(11) << memState.lSizes[1] << " bytes" << "\n " << setw(4) << memState.lCounts[2] << " CRT blocks holding " << setw(11) << memState.lSizes[2] << " bytes" << "\n " << setw(4) << memState.lCounts[3] << " Ignore blocks holding " << setw(11) << memState.lSizes[3] << " bytes" << "\n " << setw(4) << memState.lCounts[5] << " Client blocks holding " << setw(11) << memState.lSizes[4] << " bytes" << "\n Biggest Block size allocated: " << setw(8) << memState.lHighWaterCount << " bytes" << "\n Currently have allocated " << setw(11) << memState.lTotalCount << " bytes" << "\n"; } // //----< make title for display in static buffer >---------------------- const char* memCheck::makeTitle(const char *name1, const char *name2) { static char *tempStr1 = "difference between "; static char *tempStr2 = " and "; static char tempName[MAX]; char *currChar = tempName; // write tempStr1 to buffer strncpy(currChar,tempStr1,MAX); int offset = strlen(tempStr1); currChar += strlen(tempStr1); // add name1 strncpy(currChar,name1,MAX-offset); offset += strlen(name1); currChar += strlen(name1); // add tempStr2 strncpy(currChar,tempStr2,MAX-offset); offset += strlen(tempStr2); currChar += strlen(tempStr2); // add name2 strncpy(currChar,name2,MAX-offset); tempName[MAX] = '\0'; // return const pointer to static buffer return tempName; } // //----< state difference, relative to another state >------------------ void memCheck::stateDiff(const memCheck &d) { _CrtMemState temp; _CrtMemDifference(&temp,&d.memState,&memState); memCheck tempDebug(temp); tempDebug.name(makeTitle(name(),d.name())); tempDebug.state(); } //----< state difference between two memCheck objects >---------------- void stateDiff(const memCheck &d1, const memCheck &d2) { memCheck temp1 = d1; memCheck temp2 = d2; _CrtMemState temp, d1State, d2State; d1State = static_cast<_CrtMemState>(temp1); d2State = static_cast<_CrtMemState>(temp2); _CrtMemDifference(&temp,&d2State,&d1State); memCheck tempDebug(temp); tempDebug.name(memCheck::makeTitle(d1.name(),d2.name())); tempDebug.state(); } // //----< test stub >---------------------------------------------------- #ifdef TEST_MEMCHECK #include using namespace std; void main() { cout << "\n Testing memCheck Class " << "\n ========================\n"; memCheck d1("d1"); d1.state(); memCheck d2("d2"); d2.state(); if(d2 == d1) cout << "\n no memory state difference\n"; else cout << "\n memory state difference\n"; memCheck d3("d3"), d4("d4"); d3.state(); d4.state(); if(d4 == d3) cout << "\n no memory state difference\n"; else cout << "\n memory state difference\n"; d4.stateDiff(d3); stateDiff(d4,d3); string *s = new string; memCheck d5("after declaring string on heap"); d5.state(); s->resize(10000); memCheck d6("after asking for 10,000 bytes"); d6.state(); delete s; memCheck d7("after deleting string"); d7.state(); } #endif