I discovered this accidentally today when I was working on my project. Basically, in my project, I have something similar to below for resource handling.
class Resource {
public:
static Resource instance_;
~Resource () {
std::for_each(res_.begin(), res_.end(), [&] (Stuff *stuff) {
delete stuff;
});
}
private:
std::set<Stuff*> res_;
};
Running this again valgrind, upon program exit, I'm seeing some really cryptic errors. Something like this:
by 0x40DD42: std::_Rb_tree<unsigned int, std::pair<unsigned int const, std::pair<Vertex*, unsigned int> >,
std::_Select1st<std::pair<unsigned int const, std::pair<Vertex*, unsigned int> > >, std::less<unsigned int>,
std::allocator<std::pair<unsigned int const, std::pair<Vertex*, unsigned int> > > >::equal_range(unsigned int const&)
\\ a lot, lot more to come...
Reading through all this, it seems to indicate that the destructor of Resource
is freeing already freed memory region.
But my destructor is definitely handling things correctly. To prove this, I moved the deletion code out of the destructor into another member function. So, something like this:
class Resource {
public:
static Resource instance_;
~Resource () { /* does nothing */ }
void clear () {
std::for_each(res_.begin(), res_.end(), [&] (Stuff *stuff) {
delete stuff;
});
}
// ... more
};
Then, I simply call clear() on the static instance before the program exits. Now, the error no longer appears in valgrind!
To further prove that this is only to do with when a static instance dies when the program dies, I removed the static instance.
Instead of having a static instance_, I just allocated an instance of Resource
on stack in main()
when my program starts.
After this change, the problem also goes away.
Now, I'm wondering why this is happening? Does this have anything to do with the operating system?
My guess is that the OS probably attempts to free everything as the program dies, and my destructor just happens to kick in during the clean-up, not before.
The OS in question here is Linux (Ubuntu 12.10). The compiler is gcc 4.7.2.
Thanks