Even few bytes of memory leak in long run can cause trouble.
Here's what happened in my case, I was writing a Huffman Encoder in C++.
It had many class and few linked list which are sorted based on some criteria (character's frequency of occurrence).
I used MergeSort to sort the linked list of objects. As sorting disrupts the normal order of consecutive allocations of objects in Heap, calling delete will not work if the first item has been switched.
It was a messy code but it worked as I planed it to.
items = new CharNode[actualItems];
...
MergeSort::Sort (items, 0, count);
...
delete[] items;
If the above code is executed few times, then the amount of memory wasted can range in megabytes. This generally happens if your code runs as a daemon/service process for couple of days. User might not be able to detect it first time but its effect can be felt after few days.
One way to detect the memory leak is to use third party tools, but that can be expensive to you and your company.
Why not use what is given by Microsoft Visual C++ itself ?
As part of Visual Studio 2005 and onward, Microsoft provides few debugging routines to developer as part of the package.
One of the helper function which can detect memory leaks is _CrtDumpMemoryLeaks
To use the function you need to first prepare your source code with preprocessor directives , which includes defining a macro and including debug library of crt runtime :
#define _CRTDBG_MAP_ALLOC#include <stdlib.h>#include <crtdbg.h>
To dump all memory leaks add this function call just before end of your program :
_CrtDumpMemoryLeaks();
By default it dumps debug information in output window in debug session, but you can override it to output it to stdout . So put a breakpoint after the above function call and check the output window (open it from View->Output if not shown).
In my case it was pretty bad :
Detected memory leaks!Dumping objects ->normal block at 0x006EC970, 64 bytes long.Data: < - > 03 00 00 00 2D 00 00 00 00 00 00 00 00 00 00 00normal block at 0x006EC8E0, 84 bytes long.Data: < n n > 04 00 00 00 19 00 00 00 A4 C4 6E 00 B8 C4 6E 00normal block at 0x006EC838, 104 bytes long.Data: < | n n > 05 00 00 00 0E 00 00 00 7C C4 6E 00 90 C4 6E 00normal block at 0x006EC730, 124 bytes long.Data: < > 06 00 00 00 0C 00 00 00 00 00 00 00 00 00 00 00Object dump complete.
I had 376 bytes of memory leak! But how do I know where it actually happend in my source code ?
To get exact line number where the leak occurred, add more directives as :
#define _CRTDBG_MAP_ALLOC#include <stdlib.h>#include <crtdbg.h>#ifdef _DEBUG#define DEBUG_NEW new(_NORMAL_BLOCK, __FILE__, __LINE__)#define new DEBUG_NEW#endif
Now the output became more sober :
Detected memory leaks!Dumping objects ->c:\users\admin\documents\visual studio 2008\projects\huffman\huffman\linkedlist.cpp(111) : {236} normal block at 0x006EC970, 64 bytes long.Data: < - > 03 00 00 00 2D 00 00 00 00 00 00 00 00 00 00 00c:\users\admin\documents\visual studio 2008\projects\huffman\huffman\linkedlist.cpp(111) : {227} normal block at 0x006EC8E0, 84 bytes long.Data: < n n > 04 00 00 00 19 00 00 00 A4 C4 6E 00 B8 C4 6E 00c:\users\admin\documents\visual studio 2008\projects\huffman\huffman\linkedlist.cpp(111) : {216} normal block at 0x006EC838, 104 bytes long.Data: < | n n > 05 00 00 00 0E 00 00 00 7C C4 6E 00 90 C4 6E 00c:\users\admin\documents\visual studio 2008\projects\huffman\huffman\linkedlist.cpp(111) : {203} normal block at 0x006EC730, 124 bytes long.Data: < > 06 00 00 00 0C 00 00 00 00 00 00 00 00 00 00 00Object dump complete.
So all the leaks happened in same line (111 to be precise) ? Strange!
It was this line :
CharNode *list = new CharNode[this->length];
Opps! I just allocated one less item and normal house keeping data for allocation library was being overwritten while accesing last item.
CharNode *list = new CharNode[this->length + 1];
That was the remedy for 376 bytes of memory leak!!!!
It was painless in my case, but it might be more complex for you. But what ever be the complexity now you know how to find it in first place .
To modifiy behevior of debug checking , please refer documentation of _CrtSetDbgFlag .