Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Tracking down owner of a shared_ptr?

In our app we're about to (finally..) switch from raw pointers to using C++11 smart_ptr templates.

We do have the occasional bug in our app with (non C++) objects still keeping references to our C++ objects causing crashes in the past when accessing the then-dealloc'd objects.

Not sure if this is a silly question - but is there a way to take advantage of the smart_ptr objects and 'dump' the objects still holding on to the C++ objects when none are expected to hold a reference to one any more?

I guess what I'm asking for is a way to list all owners of smart_ptr<MyClass> at a certain point in time.

Any suggestions much appreciated!

like image 567
ATV Avatar asked Jul 24 '16 15:07

ATV


People also ask

Do I need to delete a shared_ptr?

The purpose of shared_ptr is to manage an object that no one "person" has the right or responsibility to delete, because there could be others sharing ownership. So you shouldn't ever want to, either.

Can shared_ptr be copied?

The ownership of an object can only be shared with another shared_ptr by copy constructing or copy assigning its value to another shared_ptr . Constructing a new shared_ptr using the raw underlying pointer owned by another shared_ptr leads to undefined behavior.

What happens when shared_ptr goes out of scope?

All the instances point to the same object, and share access to one "control block" that increments and decrements the reference count whenever a new shared_ptr is added, goes out of scope, or is reset. When the reference count reaches zero, the control block deletes the memory resource and itself.

What happens when you move a shared_ptr?

By moving the shared_ptr instead of copying it, we "steal" the atomic reference count and we nullify the other shared_ptr . "stealing" the reference count is not atomic, and it is hundred times faster than copying the shared_ptr (and causing atomic reference increment or decrement).


2 Answers

No. Without creating your own smart pointer classes that wrap std::unique_ptr and std::shared_ptr (ignore the deprecated std::auto_ptr) that tracks this information, there is no way to do that. The standard classes themself do not track this information (would be too costly).

Another alternative would be to modify the code of your standard library implementation to track that info. Less invasive on your code since you can keep using the standard names. But probably a bit more tricky than just wrapping the classes and use the wrappers.

like image 99
Jesper Juhl Avatar answered Oct 26 '22 23:10

Jesper Juhl


Don't believe this is possible for any out of the box c++ smart pointers. You can trivially wrap a shared_ptr to achieve the same effect though.

template<typename T>
class mySmartPtr : boost::noncopyable{
    public:
         // This method should be the only way this object can be copied
         // as the copy constructors are made private
         // The newOwnerName parameter can be used to populate m_onwers.
         static mySmartPtr<T> newOwner(mySmartPtr<T>&, std::string newOnwerName); 
    private:
         std::shared_ptr<T> m_ptr;
         static std::vector<std::string> m_owners;
};
like image 28
cplusplusrat Avatar answered Oct 27 '22 01:10

cplusplusrat