Home > Software engineering >  shared_from_this() crashes in specific case
shared_from_this() crashes in specific case

Time:10-24

Option 1 crashes the app on shared_from_this() with bad_weak_ptr, while option 2 works fine, why? the only difference i see is where the clone is being created - in the Clone() function or in line with creating shared_ptr for the clone, in both cases the shared_from_this requirement of already having shared_ptr with ownership of this when using shared_from_this() is met

class Base
{
public:
    virtual Base* Clone() = 0;
};

class Derived : public Base, public std::enable_shared_from_this<Derived>
{
public:
    Base* Clone() override
    {
        return new Derived(*this);
    }
    void test()
    {
        std::shared_ptr<Derived> ptr = shared_from_this();
    }
};

int main()
{
    std::shared_ptr<Base> obj = std::make_shared<Derived>();
    //std::shared_ptr<Base> clone = std::shared_ptr<Base>(obj->Clone()); // option 1
    std::shared_ptr<Base> clone = std::shared_ptr<Base>(new Derived(*std::static_pointer_cast<Derived>(obj))); // option 2
    std::shared_ptr<Derived> derived = std::static_pointer_cast<Derived>(clone);
    derived->test();

    return 0;
}

CodePudding user response:

You can't new an object that derives from enable_shared_from_this and for it to safely work since the new object doesn't actually have a shared_ptr container.

Instead of this:

Base* Clone() override
{
    return new Derived(*this);
}

This:

shared_ptr<Base> Clone() override
{
    return make_shared<Derived>(*this);
}

Similar adjustment in the base class declaration:

virtual shared_ptr<Base> Clone() = 0;
  • Related