试图在C++中打印树的内容时出现内存分配错误



我的问题可能有一个简单的解决方案,但到目前为止我一直找不到。我对C语言很陌生,这是我用C++编写的第一个程序。

我有一个函数create_complete_tree(int nr_child_nodes, int tree_depth),它制作了一个深度为int tree_depth的树,其中每个节点(除了最后一行(都有int nr_child_nodes个子节点。create_complete_tree(2,4)生成一个树,它的开头是这样的:

1
/ 
/   
2     9
/    / 
3   6 10 13
/   // /
...

我正在尝试制作一个函数print(std::ostream& str),当在上面树的根节点上调用时,它会以以下格式打印树内容:

node_1
node_2
node_3
node_4
node_5
node_6
node_7
node_8
node_9
node_10
node_11
node_12
node_13
node_14
node_15

稍后我会担心添加缩进,但现在我只专注于按正确的顺序打印节点。这就是我目前所拥有的:

void node::print(std::ostream& str) {
str << this->get_name() << std::endl;
for (int i = 0; i < this->get_nr_children(); i++) {
node child = (*this->get_child(i));
child.print(str);
}
}

此函数打印节点1-8,但随后我得到一个Segmentation fault: 11错误。我知道这个错误是由于试图访问不可用/禁止访问的内存造成的,但我很难理解这对我来说到底意味着什么。我的create_complete_tree方法如下:

void node::create_complete_tree(int nr_child_nodes, int tree_depth) {
if (tree_depth == 1) {
return;
} else {
while (this->get_nr_children() < nr_child_nodes) {
node* new_child = new node();
this->add_child(new_child);
(*new_child).create_complete_tree(nr_child_nodes, tree_depth - 1);
}
}
}

每个节点的子节点指针存储在一个称为child_nodes的向量中。感谢您花时间阅读本文。如果有任何回复能帮助我找到解决方案并更好地理解内存分配,我将不胜感激。

问题

这个代码很可能违反了规则3。以下声明:

node child = (*this->get_child(i));

创建节点的克隆。如果您没有提供规则3,但实现了析构函数,则克隆将使用与原始节点相同的指向相同子节点的指针。不幸的是,当您离开print()函数时,克隆将被销毁,析构函数将销毁子级。所有后续对这些子对象的访问都将访问一个不再存在的对象,即UB。

Segfault可能是UB的症状。如果没有node的构造函数、复制构造函数、赋值和析构函数实现,我无法确定。但是,如果有这个代码,以及这里的许多类似问题,我会惊讶地发现这将是另一个问题;-(

潜在解决方案

无论如何,正确的解决方案是实现3的trule所缺少的内容。因为如果你不这样做,你在很多情况下都会遇到类似的问题。

另一个解决方案(不是互斥的(是使用指针而不进行克隆:

void node::print(std::ostream& str) {
str << this->get_name() << std::endl;
for (int i = 0; i < get_nr_children(); i++) { // this-> is not needed
node *child = this->get_child(i);         // pointer assignment without cloning
child->print(str);                        // member invokation for a pointer
}
}

相关内容

  • 没有找到相关文章

最新更新