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 ?
Smart pointers are class objects that behave like built-in pointers but also manage objects that you create with new so that you don't have to worry about when and whether to delete them - the smart pointers automatically delete the managed object for you at the appropriate time.
The smart pointer has an internal counter which is decreased each time that a std::shared_ptr , pointing to the same resource, goes out of scope – this technique is called reference counting. When the last shared pointer is destroyed, the counter goes to zero, and the memory is deallocated.
C++11 offers two smart pointer classes, shared_ptr and unique_ptr . The unique_ptr class implements exclusive ownership semantics. This means that a unique_ptr object will claim exclusive ownership of the object it points to. When the unique_ptr object goes away, it automatically deletes the owned object for you.
Smart pointers allow you to forget about manual allocation and can help avoid most memory leaks. On managed platforms, an object gets destroyed when there are no references to it.
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_ptr
has 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 own QSharedPointer
.
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_ptr
replaces it and is much safer if you have C++11 available). It's the only place where I was ever tempted to use auto_ptr
before, as it provides a release
method.
unique_ptr<QListWidget> widget(new QListWidget(...));
// do stuff with the widget to set it up for your GUI
some_layout.addWidget(widget.release()); // <-- release ownership so that
// the layout now becomes responsible
// for memory management
// ^^ auto_ptr works above if we don't have C++11
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::destroyed
signal.
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.
Yes, most likely and No they don't and I can't see how they could. You have to rely on the contract that the thing you are passing the pointer to will not take ownership (unless the documentation states it), and if the latter, don't wrap it in a smart pointer on your side.
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