Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Trivial cases of shared_ptr and weak_ptr failing

I'm having trouble using shared_ptr and weak_ptr along with enable_shared_from_this.

When I google the symptoms of what I'm seeing, everybody suggests "you cannot use shared_from_this() when there are no shared_ptr instances owning your object.

But that's not my case.

Consider this code:

#include <memory> #include <cassert>  class MyClass : std::enable_shared_from_this<MyClass> { public:     void this_fails()     {         // Doesn't even assert(), because it throws bad_weak_ptr         assert(shared_from_this());     }     void this_fails_too()     {         std::weak_ptr<MyClass> weak = weak_from_this();         std::shared_ptr<MyClass> strong = weak.lock();         // This assert fails         assert(strong.get());     } };  int main() {     std::shared_ptr<MyClass> obj = std::make_shared<MyClass>();      obj->this_fails();     obj->this_fails_too(); }  

Both methods in MyClass crash the program. I must be missing something obvious - what is it?

like image 632
LubosD Avatar asked Jul 16 '19 19:07

LubosD


People also ask

Is Weak_ptr lock thread safe?

Using weak_ptr and shared_ptr across threads is safe; the weak_ptr/shared_ptr objects themselves aren't thread-safe. You can't read/write to a single smart pointer across threads. Access to g_s like you did isn't safe, be it a shared_ptr or a weak_ptr.

How can a Weak_ptr be turned into a shared_ptr?

The weak_ptr class template stores a "weak reference" to an object that's already managed by a shared_ptr. To access the object, a weak_ptr can be converted to a shared_ptr using the shared_ptr constructor or the member function lock.

When should I use Weak_ptr?

By using a weak_ptr , you can create a shared_ptr that joins to an existing set of related instances, but only if the underlying memory resource is still valid. A weak_ptr itself does not participate in the reference counting, and therefore, it cannot prevent the reference count from going to zero.

When to use shared_ ptr?

Use this option when the implied or explicit code contract between the caller and callee requires that the callee be an owner. Pass the shared_ptr by reference or const reference. In this case, the reference count isn't incremented, and the callee can access the pointer as long as the caller doesn't go out of scope.


1 Answers

You must inherit publicly from std::enable_shared_from_this. Inheriting privately doesn't help - std::shared_ptr can't access the base class and set it up properly.

like image 81
Igor Tandetnik Avatar answered Sep 20 '22 19:09

Igor Tandetnik