大量 shared_ptr 的分段错误
segmentation fault with large number of shared_ptr
这是我的.h文件:
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;
};
这是我的节点构造函数,它重置所有指针并将节点数增加 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++;
}
这是我的析构函数,它只是通过静态变量减少节点数 No_nodes
Board::Node::~Node()
{
if(Node::Node_no%10==0)
std::cerr << "Node destructor:"<<Node::Node_no << std::endl;
Node::Node_no--;
}
这是我的主文件
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;
}
当我在主文件中更改这一行时出现问题
for (int i = 0; i < 1000; i++) //120000
对此:
for (int i = 0; i < 120000; i++) //120000
我遇到分段错误
有什么想法吗?
我想我知道为什么会出现这个问题。每个进一步的元素通过 shared_ptr
拥有前一个元素。因此,当被删除时,第一个元素的析构函数调用第二个元素的析构函数,然后第二个元素的析构函数调用第三个元素的析构函数,依此类推,直到堆栈溢出。
要解决此问题,您应该避免在 Node
class 中使用 shared_ptr
。只需通过原始指针将 link 存储到 next/prev 节点并通过外部代码删除节点(实际上你有 ve
向量可以负责存储节点)。
这是我的.h文件:
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;
};
这是我的节点构造函数,它重置所有指针并将节点数增加 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++;
}
这是我的析构函数,它只是通过静态变量减少节点数 No_nodes
Board::Node::~Node()
{
if(Node::Node_no%10==0)
std::cerr << "Node destructor:"<<Node::Node_no << std::endl;
Node::Node_no--;
}
这是我的主文件
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;
}
当我在主文件中更改这一行时出现问题
for (int i = 0; i < 1000; i++) //120000
对此:
for (int i = 0; i < 120000; i++) //120000
我遇到分段错误 有什么想法吗?
我想我知道为什么会出现这个问题。每个进一步的元素通过 shared_ptr
拥有前一个元素。因此,当被删除时,第一个元素的析构函数调用第二个元素的析构函数,然后第二个元素的析构函数调用第三个元素的析构函数,依此类推,直到堆栈溢出。
要解决此问题,您应该避免在 Node
class 中使用 shared_ptr
。只需通过原始指针将 link 存储到 next/prev 节点并通过外部代码删除节点(实际上你有 ve
向量可以负责存储节点)。