c++constructorshared-ptrvirtual-destructormake-shared

segmentation fault with large number of shared_ptr


this I is my .h file:

class Node
    {
        
    public:
        static void disp(const std::vector<int> &v);
        static size_t Node_no;
        Node(const std::vector<int> & initial_state);
        ~Node();
        std::shared_ptr<std::vector<int>> val;
        std::shared_ptr<Node> up;
        std::shared_ptr<Node> down;
        std::shared_ptr<Node> right;
        std::shared_ptr<Node> left;
        std::shared_ptr<Node> parent;
    };

this is my node constructor that resets all pointer and increases number of nodes by 1;

Board::Node::Node(const std::vector<int> &initial_state)
{
    val = std::make_shared<std::vector<int>>(move(initial_state));
    this->right.reset();
    this->left.reset();
    this->up.reset();
    this->down.reset();
    this->parent.reset();
    Node::Node_no++;
}

this is I my destructor that just decrease number of nodes by static variable No_nodes

Board::Node::~Node()
{
    if(Node::Node_no%10==0)
        std::cerr << "Node destructor:"<<Node::Node_no << std::endl;
    Node::Node_no--;
}

and this one is my main file

int main()
{

    std::vector<int> init_vec = {2, 4, 6, 5, 8, 3, 0, 1, 7};
    std::vector<std::shared_ptr<Board::Node>> ve;
    for (int i = 0; i < 1000; i++) //120000
    {
        std::shared_ptr<Board::Node> vv = std::make_shared<Board::Node>(std::vector<int>({2, 4, 6, 5, 8, 3, 0, 1, 7}));
        if (ve.size() >= 1)
        {
            vv->down = ve[ve.size() - 1];
            vv->up = ve[ve.size() - 1];
            vv->right = ve[ve.size() - 1];
            vv->left = ve[ve.size() - 1];
            vv->parent = ve[ve.size() - 1];
        }
        ve.push_back(vv);
    }

    return 0;
}

the problem occurs when I change this line in main file

    for (int i = 0; i < 1000; i++) //120000

to this :

    for (int i = 0; i < 120000; i++) //120000

I get segmentation fault any idea?


Solution

  • I think I know why this issue happens. Each futher element owns the previous element via shared_ptr. So when being deleted the first element's destructor calls the second element's destructor, then second element's destructor calls third element's destructor and so on until your stack is overflowed.

    To fix this you should avoid using shared_ptr inside your Node class. Just store a link to next/prev node via raw pointer and delete nodes by external code (in fact you have your ve vector which can be responsible for storing nodes).