ATV
ATV

Reputation: 4496

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!

Upvotes: 10

Views: 4480

Answers (3)

Richard Hodges
Richard Hodges

Reputation: 69864

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.

This is serious and must not be ignored.

If you're giving 3rd party library components observer status on your objects, then it stands to reason that the 3rd party component's observer must not outlive your object.

There are 3 common causes for this problem:

  1. Improper lifetime management of the 3rd-party component (you're deleting the observed object before shutting down the 3rd party observer)

  2. improperly detected crossing cases (resulting in 1, above)

  3. In the case were you are the component, you must take orders on from the 3rd party framework as to when you may dispose of your object.

Before involving shared_ptrs you ought to first prove that the shared_ptr may legitimately destroy the object. If the 3rd party component has a 'deregister' method, then you can solve this by:

  1. Ensure ownership of the 3rd party component and your observed object are controlled by the same shared_ptr, or
  2. Use a custom deleter on the shared_ptr to cause de-registration on your controlled object on the 3rd party object before finally deleting it.

If none of this is clear, it's time to take a good long look at your object lifetimes. It often helps to draw sequence diagrams.

Upvotes: 2

Jesper Juhl
Jesper Juhl

Reputation: 31457

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.

Upvotes: 2

cplusplusrat
cplusplusrat

Reputation: 1445

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;
};

Upvotes: 1

Related Questions