C语言中删除完整BST后复用出现段错误,如何修复?
二叉搜索树删除后重新填充时的段错误修复问题
我想要删除整个二叉搜索树(BST),之后重新填充其他数据。以下是我的代码:
struct node { char *value; struct node *p_left; struct node *p_right; int usable; }; deleteTree(struct node* node){ if (node == NULL) { return;} deleteTree(node->p_left); deleteTree(node->p_right); free(node); } main //other things deleteTree(tree1); //fill tree2 //copy contents of tree2 into tree1 --> segfault
但树似乎并未被删除,反而被奇怪值填充,且尝试再次使用该树时出现段错误,请问该如何修复?
问题根源
- 野指针问题:当前
deleteTree函数接收的是指针副本,free(node)仅释放节点内存,但原指针tree1仍指向已释放的内存区域(成为野指针)。后续操作这个野指针会触发未定义行为,比如出现奇怪值、段错误。 - 内存泄漏(额外问题):节点中的
char* value如果是动态分配的,当前代码未释放它,会造成内存泄漏。
修复方案
修改deleteTree函数,让它接收指针的指针,这样可以在函数内部将原指针置为NULL,彻底避免野指针;同时按需释放value成员:
#include <stdlib.h> // 确保包含free的头文件 void deleteTree(struct node** node) { if (*node == NULL) { return; } // 递归删除左右子树 deleteTree(&((*node)->p_left)); deleteTree(&((*node)->p_right)); // 释放value(仅当value是动态分配时,比如用malloc/calloc分配的) free((*node)->value); // 释放节点本身 free(*node); // 将原指针置为NULL,避免后续误操作野指针 *node = NULL; }
调用时传入指针的地址:
deleteTree(&tree1);
说明
- 调用
deleteTree(&tree1)后,tree1会被置为NULL,后续重新填充数据时,从NULL开始构建新树,不会再访问已释放的内存,段错误问题即可解决。 - 如果
value是字符串字面量(比如直接赋值"abc"),不要调用free((*node)->value),否则会触发错误,根据实际内存分配情况调整即可。
内容的提问来源于stack exchange,提问作者Boazzone66
相关产品推荐
相关产品推荐

