0

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?

SeAlGhz
  • 75
  • 9
  • 1
    No errors logged with the segmentation fault? What happens when you let it fault when running under the debugger, or load the core file into the debugger? – Useless Dec 17 '20 at 14:37
  • `move(initial_state)` - moving from `const ref` is never a good idea. But probably not a source of this bug. – Quimby Dec 17 '20 at 14:37
  • @Useless thanks for your reply . I don't receive any error logged with segment fault. I use docker gcc:9.2.0 . – SeAlGhz Dec 17 '20 at 14:42
  • You should also install `gdb` and learn to use that. There's lots of information in core files! – Useless Dec 17 '20 at 14:43
  • The code shown, while not the best, doesn't appear like it will lead to a segfault. The issue is likely in code you haven't shown. – AndyG Dec 17 '20 at 14:43
  • @Quimby could you plz tell me why it's not good? – SeAlGhz Dec 17 '20 at 14:43
  • @AndyG . no this is all the code . is it possible that problem happens because of docker ? – SeAlGhz Dec 17 '20 at 14:58
  • @ali: It could very well be... you may need to increase your heap size. – AndyG Dec 17 '20 at 14:59
  • There's a lot of memory in use here, even if it's all on the heap. And a ton of fragmentation. – Yksisarvinen Dec 17 '20 at 15:00
  • AndyG I tried the command--memory="6g" for running docker but nothing chagned – SeAlGhz Dec 17 '20 at 15:11
  • @Yksisarvinen what should I do ? – SeAlGhz Dec 17 '20 at 15:12
  • thanks to @Useless i got following error using GDB Program received signal SIGSEGV, Segmentation fault. 0x0000000000403cf2 in std::__shared_count<(__gnu_cxx::_Lock_policy)2>::~__shared_count ( this=, __in_chrg=) at /usr/local/include/c++/9.2.0/bits/shared_ptr_base.h:727 727 /usr/local/include/c++/9.2.0/bits/shared_ptr_base.h: No such file or directory. – SeAlGhz Dec 17 '20 at 15:17
  • `ve[ve.size() - 1]` is `ve.back()`. – 273K Dec 17 '20 at 15:25
  • `val = std::make_shared>(move(initial_state));` There is no sense of making shared_ptr to vector, this gets an unique copy of initial_state on the heat. – 273K Dec 17 '20 at 15:28
  • @ali Because it is useless at best, you cannot move from constant objects and users are not very accustomed to `const T&&` parameters since there are very few uses for them. But it could lead to unexpected calls if some library has use for const rvalues. – Quimby Dec 17 '20 at 15:51

1 Answers1

2

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).

otter
  • 515
  • 2
  • 7
  • No idea why you got a downvote, but this is a correct answer, seeing the comment from OP. They get a crash in a `std::shared_ptr` destructor. 120000 destructor chain can well overflow a typical stack. – Yksisarvinen Dec 17 '20 at 15:44
  • my problem is solved with your help . but can you tell me is there anyway to use other smart pointer, to avoid using delete keyword? – SeAlGhz Dec 17 '20 at 15:52
  • 1
    @Yksisarvinen thanks. @ali you can use non owning smart pointers like `std::weak_ptr`. With `weak_ptr` you can check if the object is still alive prior using it. But raw pointers are also completely fine here. – otter Dec 17 '20 at 16:04
  • dear @Yksisarvinen as @otter said, my program causes stack overflow but my question is : " the latest an object is created , sooner it will be deleted . so the last created object should be destructed first , and resets it's own `shared_ptr` to nullptr so this object is not responsible for the rest of objects's `shared_ptr` . – SeAlGhz Dec 17 '20 at 16:52