You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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);
    }
}

问题出在这几步:

  1. 你把*_root赋值给了局部变量p,然后递归释放左右子树、free掉p指向的节点。但free(p)只是把内存还给了系统,调用者那边的原始指针(也就是你传入的_root指向的变量)并没有被修改成NULL。
  2. 当你后续再用这个根指针去显示树或者调用其他函数时,它仍然指向已经被释放的内存区域,这时候访问它就是典型的未定义行为,程序崩溃是必然的结果。

给你两个修复方案,任选其一都能解决问题:

方案一:在释放后置空原始指针

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 08:14:45