Introduction
Writing our own trace utility is much important for a complicated and complex
applications. This is useful since C++ does not have the concept of GC (garbage
collector) unlike C# or java which automatically takes care of those issues. A
good trace file can help a lot if you are trying find bugs or hard to find memory
leaks that often raise during the production of the application.
So what we need is an easy utility that detects the memory leaks in place when the
application is run. That also finds out where exactly the memory leak are and how
many bytes of memory are not freed.
Using the code
Mainly we wanted to rewrite the new function so that when ever new is
called it adds the trace and of course for delete we have to remove the trace.
Both the methods should be in synchronous with each other failing to call delete
will trigger memory leak.
#define DEBUG_NEW new(__FILE__, __LINE__)
inline void * __cdecl operator new(size_t size,
const char *fileName, int lineNumber)
{
void *ptr = (void *)malloc(size);
addTrace((DWORD)ptr, size, fileName, lineNumber);
return(ptr);
};
For Delete this is supposed to be called:
void __cdecl operator delete(void *p)
{
removeTrace((DWORD)p);
free(p);
};
For checking the results we need a helper method that walks us through the memory leaks:
void Dump()
{
AllocatedList::iterator i;
DWORD totalSize = 0;
char buf[1024];
if(!allocatedList)
return;
for(i=allocatedList->begin(); i!=allocatedList->end(); i++)
{
sprintf(buf,
"%-50s:\t\tLINE %d,\t\tADDRESS %d\t%d NOTFREED\n",
(*i)->fileName,
(*i)->lineNumber,
(*i)->address,
(*i)->size);
printf("%s",buf);
totalSize += (*i)->size;
}
sprintf(buf, "\n---------------------------------\n");
printf("%s",buf);
if(!totalSize)
{
sprintf(buf,"There are no MEMORY LEAKS\n");
printf("%s",buf);
}
else
{
sprintf(buf,
"Total UNFREED MEMORY: %d bytes\n",
totalSize);
printf("%s",buf);
}
};
I have used a List to iterate walk the elements.
main()
{
char *str = "This is a Testing Program";
int len = strlen(str);
char *ptr;
ptr = DEBUG_NEW char[len+1];
strcpy(ptr,str);
delete ptr;
Dump();
}
Take a look at the main function: instead of calling new char[len+1];
I am calling DEBUG_NEW. This will add the trace and delete will remove the trace.
I still can't find out if there was a way to call new instead of DEBUG_NEW directly.