Introduction
Writing our own trace utility is much important for 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 to find hard-to-find memory leaks that often arise during the production of an application.
So, what we need is an easy utility that detects the memory leaks in place when the application is run. Also, that finds out where exactly the memory leak is and how many bytes of memory is not freed.
Using the code
Mainly, we want to rewrite the new
function so that whenever new
is called, it adds the trace, and of course, for delete
, we have to remove the trace. Both the methods should be ssynchronous with each other; failing to call delete
will trigger a memory leak.
#define 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);
};
void __cdecl operator delete(void *p)
{
removeTrace((DWORD)p);
free(p);
};
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);
}
};
For checking the results, we need a helper method that walks us through the memory leaks. Finally, we write a method that shows exactly where the memory is leaking, what is the address, and how many bytes are leaked.
main(){
char *str = "This is a Testing Program";
int len = strlen(str);
char *ptr;
ptr = 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 New
. This will add the trace, and delete
will remove the trace.
Hope this one is useful too.