C语言二叉树释放函数调用后后续操作崩溃问题求助
二叉树释放函数导致后续崩溃的问题分析与修复
嘿,我一眼就看出你这个问题的症结所在——释放节点后没有把原始指针置空,导致后续操作踩了悬空指针(野指针)的坑!
先看看你的代码:
void free_tree(tree *_root) { //testing, not working tree p= *_root; if (p) { if (p->left) free_tree(&p->left); if (p->right) free_tree(&p->right); free(p); } }
问题出在这几步:
- 你把
*_root赋值给了局部变量p,然后递归释放左右子树、free掉p指向的节点。但free(p)只是把内存还给了系统,调用者那边的原始指针(也就是你传入的_root指向的变量)并没有被修改成NULL。 - 当你后续再用这个根指针去显示树或者调用其他函数时,它仍然指向已经被释放的内存区域,这时候访问它就是典型的未定义行为,程序崩溃是必然的结果。
给你两个修复方案,任选其一都能解决问题:
方案一:在释放后置空原始指针
void free_tree(tree *_root) { if (_root == NULL) return; // 先确保传入的指针地址合法 tree p = *_root; if (p) { free_tree(&(p->left)); // 不用提前判断子节点是否为空,函数内部会处理 free_tree(&(p->right)); free(p); *_root = NULL; // 关键一步!把调用者的原始指针置空 } }
这个方案在free节点后,直接修改*_root为NULL,这样调用者那边的根指针就会变成NULL,后续操作判断指针是否为空时,就不会去访问已释放的无效内存了。
方案二:更直接的写法(去掉局部变量p)
void free_tree(tree *_root) { // 先判断传入的指针本身是否为空,或者指向的节点是否为空 if (_root == NULL || *_root == NULL) return; // 递归释放左右子树 free_tree(&((*_root)->left)); free_tree(&((*_root)->right)); // 释放当前节点 free(*_root); // 置空原始指针 *_root = NULL; }
这种写法更简洁直接,全程操作原始指针的指向,从根源上避免了悬空指针的问题。
额外注意事项
- 调用这个函数时,一定要传入根节点指针的地址,比如
free_tree(&root);,这样函数才能修改你原来的root变量。 - 后续操作树的函数(比如显示结构),开头一定要先判断指针是否为NULL,比如:
void print_tree(tree root) { if (root == NULL) { printf("树已为空\n"); return; } // 其他打印逻辑 }
内容的提问来源于stack exchange,提问作者Hocine Abdellatif Houari
相关产品推荐
相关产品推荐

