【问题标题】:Why am I getting segmentational fault with weak_ptr为什么我的 weak_ptr 出现分段错误
【发布时间】:2020-08-14 11:22:32
【问题描述】:

我正在做一个练习来了解共享指针和弱指针。

所以这个例子是shared_ptr的循环依赖,我该如何解决weak_ptr的问题。

我想将 root->left->parent 初始化为 root,右节点也一样,但它给了我分段错误。

有人知道这个问题,我应该如何编写和初始化它?

这是我的代码。

要知道,我的第一个练习是只使用共享指针来完成所有操作,但之后将 parent 更改为weak_ptr,这就是为什么会有注释行

提前致谢

#include <iostream>
#include <memory>
#include <string>

using namespace std;

struct Node {
    string name;
    shared_ptr<Node> left = nullptr;
    shared_ptr<Node> right = nullptr;
//    shared_ptr<Node> parent=nullptr; 
    weak_ptr<Node> parent;
    
    Node(string x) : name(x) { cout << "Constructor" << name << endl; }
    ~Node() { cout << "Destructor " << name << endl; }

    string toString() {
        string lStr{ "<none>" }, rStr{ "<none>" }, pStr{ "<none>" }; 

        if (left != nullptr) lStr = left->toString();
        if (right != nullptr) rStr = right->toString();
        
//      if (parent != nullptr) pStr = parent->name; 
        pStr = parent.lock()->name; 

        string res;
        res += "{Me:" + name + " ";
        res += "Parent:" + pStr + " "; 
        res += "Left:" + lStr + " ";
        res += "Right:" + rStr + "}";
        return res;
    }
    
};


shared_ptr<Node> foo() {
    shared_ptr<Node> root = make_shared<Node>("rootname");
    root->left = make_shared<Node>("leftname");
    root->right = make_shared<Node>("rightname");
    
    root->left->parent = {root};
    root->right->parent ={root};
    
    return root;
}

int main()
{
    shared_ptr<Node> k = foo();
    cout << k->toString() << endl;
    return 0;
}

【问题讨论】:

  • parent.lock() 失败时,pStr = parent.lock()-&gt;name; 崩溃。
  • 您告诉我,那一刻父级不是对象的所有者。我不明白为什么@Eljay
  • 您之前收到的if (parent != nullptr) 处理了同样的情况...
  • 这类问题最好使用debugger 解决。使用调试器是一项非常宝贵的编程技能。
  • @Jarod42 那行是我使用 shared_ptr 的时候,但是我读到当你使用 weak_ptr 时你不能问 if (p == nullptr) ...

标签: c++ c++17 shared-ptr weak-ptr


【解决方案1】:
//      if (parent != nullptr) pStr = parent->name; 
        pStr = parent.lock()->name; 

应该是

    if (auto parentPtr = parent.lock()) pStr = parentPtr->name; 

parent.lock() 可能返回 null std::shared_ptr

【讨论】:

    【解决方案2】:

    它在这一行崩溃:

    pStr = parent.lock()->name;
    

    因为parent 没有为根节点初始化。我不知道你对根项的逻辑是什么,但你必须检查锁定的结果,如果它无效,用 pStr 做其他事情。

    if (auto res = parent.lock()) {
        pStr = res->name;
    } else {
        pStr = "root";
    }
    

    【讨论】:

    • 你能告诉我这段代码(没有weak_ptr)中shared_ptr的问题是他没有调用析构函数,因为他无法完成链接共享指针的循环吗?
    猜你喜欢
    • 2018-01-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-23
    相关资源
    最近更新 更多