A simple memory leak Checker ...

I implemented a free simple memory checker for heap memory which is dynamically newed and deleted. This implementation is very rudimentary (for example, for better overload new and delete, one needs to study those souce code such as on the linux platform source tree to do the correct and better one). but I hope probably one can get something from it. The idea is to overload the new and delete operators, so when new or delete is called, it will printed out where it happened by printing out the filename and line number. The user can analysis the output to get the result. The implementation I gave is so simple, and there are so many places to improve, such as to create a stack or list to push the filename and lineno for the new case as a node into the list, and delete the node correspondingly when calling delete. Then when the test program finishes, you can try to dump out the nodes in that stack/list. If there are any, then it means there is possible memory leakage.

Sample output:

~/pingMLeak>./a.exe
newed at file test2.c at line 19 for 0x6a02d8 size 4
newed at file test2.c at line 20 for 0x6a06f0 size 8
newed at file test2.c at line 22 for 0x6a0700 size 16
deleted at file test2.c at line 27 deleted for 0x6a02d8
deleted at file test2.c at line 28 deleted for 0x6a06f0
deleted at file test2.c at line 29 deleted for 0x6a0700
~/pingMLeak>

From the above output, we can seen that at the test2.c source code, line19, line20, and line22 called new operator, and it was deleted correspondingly at line27, line28 and line29. From the memory address, you can see that those 3 are matching ones.

The prototype of the sample Header file:

I am giving the leakCheck.H file. You can add this header file into you sample code like the example I am going to show you. Then make and run it.
#include <iostream>
using namespace std;

/////////////////////////////////////////////////////////////
//Start
/////////////////////////////////////////////////////////////
static const char *fname_delete;
static int lineno_delete;

void *operator new(size_t, const char *, int);
void *operator new[](size_t, const char *, int);
void operator delete(void *);
void operator delete[](void *);
void deletep(const char *, int);

void *operator new(size_t size, const char *file, int lineno) {
    void *pfs = malloc(size);
    if(NULL == pfs)
        {cerr<<"no heap to allocate"<<endl; exit(-1);}
    cout<<"newed at file "<<file;
    cout<<" at line "<<lineno<<" for ";
    cout<<hex<<pfs<<dec<<" size "<<(int)size<<endl;
    return pfs;
}

void *operator new[](size_t size, const char *file, int lineno)
{
    return operator new(size, file, lineno);
}

void operator delete(void *pfs)
{
    free(pfs); // free pointer
    cout<<"deleted at file "<<fname_delete;
    cout<<" at line "<<lineno_delete<<" ";
    cout<<" deleted for "<<hex<<pfs<<dec<<endl;
    return;
}

void operator delete[](void *pfs)
{
    operator delete(pfs);
}

void deletep(const char *file, int lineno)
{
    fname_delete = file;
    lineno_delete = lineno;
    return;
}

#define new new(__FILE__, __LINE__)
#define delete deletep(__FILE__, __LINE__), delete
/////////////////////////////////////////////////////////////
//End
/////////////////////////////////////////////////////////////
 

The test sample file:

~/pingMLeak>more test2.c
#include <iostream>
#include "leakCheck.H"
using namespace std;

class aclass
{
private:
    int num;
    char mychar;
public:
    aclass(int num, char mychar):num(num),mychar(mychar){}
    aclass(){num = 0; mychar='a';}
    void output(){cout<<num<<" "<<mychar<<endl;}
};


int main()
{
    int *a = new int(100);
    aclass *b = new aclass(100, 'b');
    b->output();
    aclass *c = new aclass[2];
    c[0].output();
    c[1].output();


    delete a;
    delete b;
    delete [] c;
    return 0;
}
~/pingMLeak>g++ test2.c
~/pingMLeak>./a.out
newed at file test2.c at line 19 for 0x6a02d8 size 4
newed at file test2.c at line 20 for 0x6a06f0 size 8
100 b
newed at file test2.c at line 22 for 0x6a0700 size 16
0 a
0 a
deleted at file test2.c at line no 27 deleted for 0x6a02d8
deleted at file test2.c at line no 28 deleted for 0x6a06f0
deleted at file test2.c at line no 29 deleted for 0x6a0700

The header file and the test file are here, Feel free to use it :)