我正在尝试创建一个递归函数来删除二叉树中的所有节点,其中p-> left和p-> right是指向树中下一级别的指针。但是它会给出以下错误消息:
*`./test.out'出错:双重免费或损坏(外出):0x00007ffdf0cb3650 *
struct Node {
int key;
double data;
Node * right;
Node * left;
};
void delete_tree(Node * & p){
if (p->left){
delete_tree(p->left);
}
if (p->right){
delete_tree(p->right);
}
delete p;
};
int main(){
Node * currentNod = new Node;
currentNod->key = 5;
Node * newNode = new Node;
newNode->key = 3;
Node * newNode2 = new Node;
newNode2->key = 6;
delete_tree(currentNod);
std::cout << currentNod->key << "\n";
std::cout << newNode->key << "\n";
std::cout << currentNod->left->key << "\n";
return 0;
我在网上搜索并意识到当你有指针的递归函数时会出现问题,但是delete_tree需要引用而不是副本,所以这个问题不适用于此?我不明白为什么它不起作用:(
编辑:更改了代码,问题是当我初始化currentNod时我首先创建了一个Node对象,然后我让currentNod成为该对象的指针。当我像这样初始化它时,它的工作原理。但是,它没有打印出我期望的内容。这打印:0 3 分段错误
当我希望它立即给出分段错误时。有谁知道现在可能出现什么问题?谢谢:)
答案 0 :(得分:1)
将它重新构建为析构函数会更有意义:
class Node {
public:
// some constructor, methods, ...
// destructor
~Node();
private:
int key;
double data;
Node * right;
Node * left;
};
Node::~Node(){
delete left;
delete right;
left = right = nullptr; // see note below
};
然后,您只需要delete node;
删除树的所有内容。但如果它是一个子树,你还需要确保父节点指向该节点的指针也是无效的,这样你就不会双重删除。
答案 1 :(得分:0)
好的,我认为你的问题是由于struct Node的初始化不正确。由于您以递归方式擦除所有树,因此必须确保仅删除已分配的动态内存,即必须确保仅删除已保留动态内存的节点,否则将进行编译但会在运行时生成错误。也就是说,在加入树结构之前正确初始化节点应该如下:
struct Node myNode:
myNode.right=NULL;
myNode.left=NULL;
通过上面我们确保树的终端节点指向NULL地址,因此当我们递归删除时,我们将只删除不指向该地址的节点。然后函数的新代码void delete_tree(Node *&amp; p)然后函数的代码工作:
void delete_tree(Node * & p){
if (p->left){
delete_tree(p->left);//Only deleted if p->left is different from NULL
}
if (p->right){
delete_tree(p->right);//Only deleted if p->right is different from NULL
}
delete p;
p=NULL; //Good Programming Practice
};