Finally I tracked down very strange bug, which is caused by double calling destructor. Here is the minimal code that reproduces the bug:
#include <iostream>
#include <memory>
#include <set>
class cEventSystem {
public:
cEventSystem() {
std::cout << "constructor: " << this << std::endl;
}
~cEventSystem() {
std::cout << "destructor: " << this << std::endl;
}
};
class cSubscriber {
public:
cSubscriber(cEventSystem& eventSystem) : eventSystem(eventSystem) {}
virtual ~cSubscriber() {}
virtual void onEvent() = 0;
protected:
cEventSystem& eventSystem;
};
class cTileBrowser: public cSubscriber {
public:
cTileBrowser(cEventSystem eventSystem) : cSubscriber(eventSystem) {}
void onEvent() {}
};
class cGui: public cSubscriber {
public:
cGui(cEventSystem& eventSystem) : cSubscriber(eventSystem) {
tileBrowser = std::make_shared<cTileBrowser>(eventSystem);
}
void onEvent() {}
std::shared_ptr<cTileBrowser> tileBrowser;
};
int main() {
cEventSystem eventSystem;
cGui gui(eventSystem);
}
The output is:
constructor: 0x7fffffffe67f
destructor: 0x7fffffffe2df
destructor: 0x7fffffffe67f
As you can see the first destructor is unwanted and it is called on different object which wasn't constructed at all (the adress is different), but in my real code the adress is close enough and it corrupts the containers I have in event system.
Debugging shows that it is make_shared which causes that destructor call.
What causes that unwanted destructor call and how can I get rid of it? I use g++4.7 with c++11 flag.
The problem is that the unwanted destructor call usually (90% of times) corrupts my event system containers in my real code which causes segfaults, but rarely it doesn't corrupt it and everything works.
The CTileBrowser constructor is taking its argument by value. You're likely seeing the destruction of a temporary copy created for that constructor. Change it to a reference parameter and I bet the problem will go away.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With