This question always troubles me especially when I’m programming with Qt.
Since Qt uses Object Ownership trees, passing a pointer e.g. via myBoostSharedPtr.get() can implicitly transfer ownership.
Now consider the case where some Qt Object gets destroyed and the whole Object Tree is destroyed but the smart-pointer is still alive e.g. as member of a different class.
What happens if the smart-pointer gets deleted afterwards ?
Double deletion with all the nasty consequences ?
Do some smart-pointer implementations prevent this ?
This question always troubles me especially when I’m programming with Qt. Since Qt uses
Share
I’m so tempted to do a rant on the weaknesses of Qt’s memory model where a lot of the API still accepts raw pointers with the expectation that the client allocates it while the QObject that accepted the pointer deletes it.
The answer to your question is undefined behavior.
shared_ptrhas no mechanism to detect if the pointer is deleted by something other than shared_ptr itself, so it will generally try to free the pointer a second time (calling delete on a dangling pointer). If you want to use shared_ptr, you have to stick with shared_ptr as the sole memory manager. This is true even for Qt’s ownQSharedPointer.What I normally did to try to get my code reasonably exception-safe when using something like Qt was to use the now deprecated
auto_ptr(unique_ptrreplaces it and is much safer if you have C++11 available). It’s the only place where I was ever tempted to useauto_ptrbefore, as it provides areleasemethod.If you need to keep a persistent pointer to your object after it is already being memory-managed by Qt (ex: a pointer to your widget after you inserted it into a layout), just use a regular pointer. There’s not really much better you can do since Qt is now the memory manager for that object.
However, you can detect when the object is destroyed (and therefore when the pointer is invalidated) through the
QObject::destroyedsignal.If you want to get really sophisticated, you could build a shared pointer type which only stores subclasses of QObject. Since QObject provides a destroyed signal, this kind of custom smart pointer could detect when QObject is destroyed through the destroy signal and avoid trying to delete the object a second time. However, it might get hairy relying on this signal in multithreaded code, and if you do implement a shared pointer, it can become quite a burden dealing with atomic reference counting, capturing a deletion function at the site the pointer is constructed (to avoid module boundary new/delete mismatches), etc.