shared_ptr - 它为什么会破坏?

时间:2014-04-01 09:45:06

标签: c++ shared-ptr

在开发类似树的数据结构时,我写了类似的东西:

    #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类型的未捕获异常终止”)< / strong>为什么?

修改 所以根据答案,我想出了似乎有效的版本:

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

3 个答案:

答案 0 :(得分:4)

为了完成这项工作,enable_shared_from_this<Node>必须为自己存储weak_ptr<Node>。此weak_ptr默认构造为null。当构造shared_ptr来接管对象的所有权时,无论是make_shared还是通过传递原始指针,它都会设置weak_ptr来引用新的shared_ptr。如果您随后在对象上调用shared_from_this(),则weak_ptr会获得lock,并且可以返回另一个shared_ptr

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

长话短说:不要在不属于shared_ptr的对象上调用{{1}} - 尤其不要在示例中基于堆栈的对象上调用。 / p>

答案 1 :(得分:2)

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

答案 2 :(得分:1)

shared_ptr假设对象已在堆上分配,但您已将其分配到堆栈上。

改为使用new,让shared_ptr为您致电delete