I don’t know why I have a memory leak here and would really appreciate any advice.
Notice that before the process terminates I call destroy(), a static member function that is supposed to delete the singleton object.
Here’s the relevant code and valgrind’s messaeg:
Manager.h:
class Manager {
public:
// Constructor/destructor
static Manager * instance();
static void destroy();
~Manager();
// Bunch of functions that I didn't write here
private:
Manager();
static Manager * _singleton;
// Bunch of fields that I didn't write here
};
Manager.cpp:
#include "Manager.h"
Manager * Manager::_singleton = NULL;
Manager * Manager::instance() {
if (_singleton == NULL) {
_singleton = new Manager();
}
return _singleton;
}
void Manager::destroy()
{
delete _singleton;
_singleton = NULL;
}
/*
* Destructor
*/
Manager::~Manager() {
// Deleting all fields here, memory leak is not from a field anyway
}
And here’s valgrind’s report:
==28688== HEAP SUMMARY:
==28688== in use at exit: 512 bytes in 1 blocks
==28688== total heap usage: 12 allocs, 11 frees, 10,376 bytes allocated
==28688==
==28688== 512 bytes in 1 blocks are definitely lost in loss record 1 of 1
==28688== at 0x4C27297: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==28688== by 0x4014CE: Manager::Manager() (Manager.cpp:33)
==28688== by 0x401437: Manager::instance() (Manager.cpp:15)
==28688== by 0x4064E4: initdevice(char*) (outputdevice.cpp:69)
==28688== by 0x406141: main (driver.cpp:21)
==28688==
==28688== LEAK SUMMARY:
==28688== definitely lost: 512 bytes in 1 blocks
==28688== indirectly lost: 0 bytes in 0 blocks
==28688== possibly lost: 0 bytes in 0 blocks
==28688== still reachable: 0 bytes in 0 blocks
==28688== suppressed: 0 bytes in 0 blocks
Why do I have this leak? I do delete _singleton in destroy()
As I said I would appreciate any help, thanks!
There are several things to note here. The most obvious is: when do you
call
Manager::destroy. The second thing is that the memoryvalgrindseems to be complaining about is allocated in the constructor of
Manager, which you don’t show us. If we can believe the error message(and I’ve generally found
valgrindto be reliable in this respect,although it can be fooled), there is no remaining pointer to the memory;
either you’re not deleting one of the fields in the object, or the
object allocates memory in its constructor which it doesn’t save in a
field.
Finally, it’s usually better practice not to destruct a singleton.
The whole purpose of the singleton idiom is to avoid order of
initialization issues (in C++, at least—otherwise, just declaring
a static instance of the object is sufficient). Destructing the object
introduces possible order of destruction issues. If you don’t destruct
it,
valgrindwill warn about possible memory leaks (not “definitlylost”); you can either ignore the warnings, or filter them out.