Search code examples
c++c++17shared-ptrweak-ptr

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

Solution

  • //      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.