简体   繁体   中英

Why am I getting segmentational fault with weak_ptr

I am doing an exercise to get to know the shared pointer and weak pointer.

So the example is with cyclic dependence of shared_ptr and how could I solve the problem with weak_ptr.

I want to initialize the root->left->parent to root and the same for right node but it is giving me segmentational fault.

Does anybody know something about this problem, how should I write and initialize it?

Here is my code.

Just to know, my first exercise was to do it all with only shared pointer, but after that to change parent to be the weak_ptr, so that's why there are commented lines

Thanks in advance

#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;
}
//      if (parent != nullptr) pStr = parent->name; 
        pStr = parent.lock()->name; 

should be

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

parent.lock() might return null std::shared_ptr .

It crashes at this line:

pStr = parent.lock()->name;

because parent is not initialized for the root node. I do not know what your logic for the root item is, but you must check the result of lock, and if it is not valid do smth else with pStr.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM