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
相关产品推荐
相关产品推荐

