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

无法向二叉树插入节点:代码实现故障排查求助

二叉树插入节点后为空的问题排查

核心问题分析

你的代码存在三个关键错误,直接导致插入节点后树始终为空,甚至会引发内存错误:


1. 指针传递方式错误

C语言中函数参数是值传递,你当前的BVSCreate_function和BVSInsert_function使用TNodef *rootPtr作为参数,函数内部修改的只是这个形参的副本,完全不会影响外部的实参指针。比如调用BVSCreate_function(rootPtr, token)时,函数里的rootPtr = newPtr只是修改了局部变量,外部的根指针根本没被更新,所以树始终是空的。

解决方式:改用指针的指针(TNodef **)传递,这样才能修改外部指针的指向。


2. BVSCreate_function的内存管理错误

你在函数中先通过malloc分配了newPtr,但紧接着执行newPtr = &init,直接丢弃了malloc的内存(造成内存泄漏),而且init是栈上的局部变量,函数执行完毕后会被销毁,newPtr变成野指针,后续访问会触发未定义行为。

同时,newPtr->content指向的initStr也是栈上的局部string变量,同样会在函数退出后失效。

解决方式:直接使用malloc分配的节点内存,同时为content指向的string结构体也分配堆内存,避免使用栈上的局部变量。


3. strCpyStr的空指针访问问题

当newPtr->content->str为NULL时,第一次调用strCpyStr,如果token.content的长度大于0,strcpy会尝试向NULL指针写入数据,直接触发程序崩溃。

解决方式:在strCpyStr中处理str为NULL的情况,确保写入前有合法的内存空间。


修正后的代码示例

修正后的节点创建与插入函数

void BVSCreate_function(TNodef **rootPtr, function_save token) {
    // 为二叉树节点分配堆内存
    TNodef *newPtr = malloc(sizeof(struct tnodef));
    if (newPtr == NULL) {
        fprintf(stderr, "99");
        return;
    }
    // 为content指向的string结构体分配堆内存
    newPtr->content = malloc(sizeof(string));
    if (newPtr->content == NULL) {
        free(newPtr);
        fprintf(stderr, "99");
        return;
    }
    // 初始化string结构体
    newPtr->content->str = NULL;
    newPtr->content->length = 0;
    newPtr->content->alloc = 0;
    // 初始化节点其他字段
    newPtr->leftPtr = NULL;
    newPtr->rightPtr = NULL;
    newPtr->return_type = token.ret_value;
    newPtr->parameters = token.param_count;
    // 复制字符串内容,失败则回滚内存分配
    if (strCpyStr(newPtr->content, token.content) != 0) {
        free(newPtr->content->str);
        free(newPtr->content);
        free(newPtr);
        fprintf(stderr, "String copy failed");
        return;
    }
    // 修改外部指针的指向
    *rootPtr = newPtr;
}

void BVSInsert_function(TNodef **rootPtr, function_save token) {
    if (*rootPtr == NULL) {
        BVSCreate_function(rootPtr, token);
    } else {
        int cmpResult = strCmpStr(token.content, (*rootPtr)->content);
        if (cmpResult < 0) {
            BVSInsert_function(&((*rootPtr)->leftPtr), token);
        } else if (cmpResult > 0) {
            BVSInsert_function(&((*rootPtr)->rightPtr), token);
        }
        // 字符串相等的情况可根据需求处理(如忽略、更新节点)
    }
}

修正后的strCpyStr函数

int strCpyStr(string *s1, string *s2) {
    int len2 = s2->length;
    // 处理空指针或内存不足的情况
    if (s1->str == NULL || len2 > s1->alloc) {
        char *newStr = realloc(s1->str, len2 + 1);
        if (newStr == NULL) {
            return 1;
        }
        s1->str = newStr;
        s1->alloc = len2 + 1;
    }
    // 复制字符串,处理空字符串场景
    if (len2 == 0) {
        s1->str[0] = '\0';
    } else {
        strcpy(s1->str, s2->str);
    }
    s1->length = len2; // 注释说明length是字符串长度,不包含终止符,因此无需+1
    return 0;
}

内容的提问来源于stack exchange,提问作者Marcin Sochacki

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 09:35:22