shared_ptr语言 - 为什么它会破裂

shared_ptr - why does it break?

本文关键字:为什么 ptr 语言 shared      更新时间:2023-10-16

在开发树状数据结构时,我写了这样的东西:

    #include <memory>
    class Node: public std::enable_shared_from_this<Node> {
    public:
        void set_root(Node & n);
    private:
        std::shared_ptr<Node> root;
        std::shared_ptr<Node> leaf;
    };
    void Node::set_root(Node & n) {
        root = n.shared_from_this();
        n.leaf = shared_from_this();
    }
    int main() {
        Node n1, n2;
        n1.set_root(n2);
    }

代码使用 clang 编译,但中断运行时("libc++abi.dylib:终止,未捕获类型为 std::__1::bad_weak_ptr:bad_weak_ptr") 为什么

编辑因此,根据答案,我想出了似乎有效的版本:

    #include <memory>
    class Node;
    typedef std::shared_ptr<Node> Node_SP;
    class Node: public std::enable_shared_from_this<Node> {
    public:
        void set_root(Node & n);
    private:
        std::shared_ptr<Node> root;
        std::shared_ptr<Node> leaf;
    };
    void Node::set_root(Node & n) {
        root = n.shared_from_this();
        n.leaf = shared_from_this();
    }
    int main() {
        Node_SP n1 = std::shared_ptr<Node>(new Node);
        Node_SP n2 = std::shared_ptr<Node>(new Node);
        n1->set_root(*n2);
    }

为了完成它的工作,enable_shared_from_this<Node>必须为自己存储一个weak_ptr<Node>。此weak_ptr默认构造为 null。当构造shared_ptr以接管对象的所有权时,无论是 vía make_shared 还是通过传递原始指针,它将所述weak_ptr设置为引用该新shared_ptr。如果随后对对象调用shared_from_this(),则weak_ptrlock ed,并且可以返回另一个shared_ptr

但是,在您的情况下,没有shared_ptr持有n1n2,因此当调用shared_from_this()时,lock在空weak_ptr上执行,导致所述异常。

长话短说:不要对不属于shared_ptr的对象调用shared_from_this() - 尤其是不要像示例中那样在基于堆栈的对象上调用。

shared_ptr假定对象是在堆上分配的,但您已在堆栈上分配了它。

请改用new,让shared_ptr为您呼叫delete

在对对象 t 调用 shared_from_this 之前,必须有一个拥有 t 的 std::shared_ptr。

相关文章: