Skip to content

Just some note about using macro and operator overriding to detect memory leak in C++

Notifications You must be signed in to change notification settings

meowyih/memleak

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

5 Commits
 
 
 
 
 
 
 
 

Repository files navigation

Detect memory leak in C++ using macro and operator overriding

Solution 1

Using macro to replace 'new int' into 'new(__FILE__,__LINE__) int' and override the 'new(size_t, const char*, int)'

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

    void operator delete(void* p) {...};
    void operator delete[](void* p) {...};

    #define new new(__FILE__, __LINE__)

Problem:

  • It does not work on Class object creation.
    MyClass* cls = new MyClass(); // this one won't work
  • It does not work on placement new.
    int* x = new(std::nothrow) int; // this one won't work

Solution 2

Replace 'new int' with 'Memleak(__FILE__,__LINE__) << new int' and overload operator << in Memleak class.

class Memleak
{
public:
    Memleak(const char* file, int line) : file_(file), line_(line) {}

    template <class T>
    T * operator << (T* t) const
    {
        // allocate an object t at line_ in file_
        return t;
    }

private:
    const char* file_;
    int line_;
};

#define new Memleak(__FILE__,__LINE__) << new

void operator delete(void* p) {...}
void operator delete[](void* p) {...}

Problem

It does not work when delete an class object, like this:

    MyClass* cls = new MyClass(); // this one works
    delete cls; // this one calls class' static delete member instead of global

Solution 3

Similar to solution 2, but also replace 'delete x' into 'Memleak(__FILE__,__LINE__) >>' and overload operator >> in Memleak class.

class Memleak
{
public:
    Memleak(const char* file, int line) : file_(file), line_(line) {}

    template <class T>
    T * operator << (T* t) const
    {
        // allocate memory and keep track file_, line_, t
        return t;
    }

    template <class T>
    T * operator >> (T* t) const
    {
        // delete memory and keep track of file_, line_, t
        return t;
    }

private:
    const char* file_;
    int line_;
};

#define new Memleak(__FILE__,__LINE__) << new
#define delete Memleak(__FILE__,__LINE__) >>

Problem

The keyword 'delete' is not only for deleting dynamic object usage. For example:

    class MyClass
    {
    public:
        // 'delete' will be replaced by macro,
        // this kind of syntax happens a lot in STL,
        // it almost not possible to avoid it.
        MyClass(MyClass const&) = delete;
    };

Solution 4

Override both global and in-class new/delete operator

void* operator new(size_t size) {...}
void* operator new[](size_t size) {...}
void operator delete(void* p) {...}
void operator delete[](void* p) {...}

class MyClass
{
...
#ifdef DEBUG_MEMORY
public:
    static void* operator new(size_t size) {...}
    static void* operator new[](size_t size) {...}
    static void operator delete(void* p) {...}
    static void operator delete[](void* p) {...}
#endif
};

Problem:

Debug information such as __FILE__ and __LINE__ only provides information that not very useful. We know which class has memory leak but does not know where it had been created.

Conclusion

Personally I uses solution 4 for the project that does not have it own memory pool at beginning. Although debug information is not enough, but better than nothing.

About

Just some note about using macro and operator overriding to detect memory leak in C++

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages