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

BST代码执行异常:无‘s’输出且核心转储问题排查

排查BST代码Core Dump及输出异常问题

核心问题排查方向

结合你描述的现象(仅输出1、2、3、4,无‘s’输出且Core Dump),问题大概率出在文件读取逻辑、BST节点内存管理或空指针访问上,以下是具体排查步骤:

1. 文件读取逻辑错误(跳过前3行+读取第4行)

如果跳过前3行时处理不当,会导致后续读取失败或处理空字符串,触发崩溃:

  • 必须检查文件打开状态:如果输入文件路径错误或权限不足,fopen会返回NULL,后续操作直接崩溃。添加检查:
    FILE *fp = fopen("input.txt", "r");
    if (fp == NULL) {
        perror("无法打开输入文件");
        return 1;
    }
    
  • 正确跳过前3行:循环调用fgets时要判断是否读到EOF(文件不足3行的情况),避免后续读取第4行时拿到NULL:
    char buf[256];
    for (int i = 0; i < 3; i++) {
        if (fgets(buf, sizeof(buf), fp) == NULL) {
            fprintf(stderr, "输入文件不足3行\n");
            fclose(fp);
            return 1;
        }
    }
    
  • 处理读取到的字符串:fgets会把换行符\n读入缓冲区,必须先去除,否则插入BST的字符串会带换行符,影响比较逻辑:
    buf[strcspn(buf, "\n")] = '\0'; // 替换换行符为字符串结束符
    

2. BST节点内存管理错误(addNode函数)

这是Core Dump最常见的原因,尤其是字符串的浅拷贝或空指针未处理:

  • 禁止直接赋值缓冲区指针:如果直接把fgets的缓冲区地址赋值给节点的data,后续缓冲区被覆盖或释放后会出现野指针,正确做法是为字符串分配独立内存:
    错误写法:
    Node *newNode = malloc(sizeof(Node));
    newNode->data = buf; // 浅拷贝,buf是栈上缓冲区,后续会被覆盖
    
    正确写法:
    Node* createNewNode(char *str) {
        Node *newNode = malloc(sizeof(Node));
        if (newNode == NULL) {
            perror("分配节点内存失败");
            return NULL;
        }
        newNode->data = strdup(str); // 复制字符串到堆内存
        if (newNode->data == NULL) {
            free(newNode); // 字符串分配失败时要释放节点内存
            perror("复制字符串失败");
            return NULL;
        }
        newNode->left = newNode->right = NULL;
        return newNode;
    }
    
  • 处理根节点为空的情况:如果根节点初始为NULL,addNode必须返回新创建的节点作为新根,否则根节点永远是NULL,后续访问root->data会触发空指针崩溃:
    Node* addNode(Node *root, char *str) {
        if (root == NULL) {
            return createNewNode(str);
        }
        int cmp = strcmp(str, root->data);
        if (cmp < 0) {
            root->left = addNode(root->left, str);
        } else if (cmp > 0) {
            root->right = addNode(root->right, str);
        }
        // 相等则不插入(根据需求调整)
        return root;
    }
    

3. 输出‘s’的逻辑问题

如果s的输出代码在addNode之后,那么程序在执行到输出前就已经崩溃,所以先解决Core Dump问题,才能看到s的输出。可以把输出s的代码提前到文件读取完成后、调用addNode之前,验证是否能正常输出,逐步缩小问题范围。

调试技巧

  • 使用gdb定位崩溃点:运行gdb ./你的程序名 core,然后输入bt查看调用栈,直接找到崩溃的代码行。
  • 在关键步骤加调试输出:比如跳过3行后输出“已跳过前3行”,读取第4行后输出“读取到字符串:%s”,addNode前后输出日志,确认程序执行到哪一步崩溃。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 14:13:11