为何C程序输出末尾会出现Segmentation fault (core dumped)错误?
解决你的Segmentation Fault问题
嘿,我帮你找出导致段错误的几个关键问题,咱们一步步来修复:
核心问题分析
- 循环条件完全错误:你main函数里用
strlen(*lines)作为循环终止条件,这是取第一行字符串的长度,而不是你实际读取的总行数。比如第一行如果有15个字符,循环会跑15次,但你可能只读取了6行,当i超过5时,lines[i]指向的是未初始化的垃圾内存,访问它直接触发段错误。 - 没有标记行数组的末尾:
FileOpen分配了100个char*的空间,但没在最后一行后面放NULL,调用者根本没法知道实际读了多少行。 - 换行符处理有内存越界隐患:
buff[strlen(buff)-1] = '\0';假设fgets一定读到了换行符,但如果文件最后一行没换行,或者遇到空行时,strlen(buff)可能为0,strlen(buff)-1就变成-1,直接越界写入内存,破坏数据。 - 遗漏了文件关闭和内存释放:原代码没关闭打开的文件,也没释放分配的内存,会导致资源泄漏。
修复后的完整代码
#include<stdio.h> #include<stdlib.h> #include<string.h> // 新增参数返回实际读取的行数 char** FileOpen(char *path, int *out_line_count); int main(void) { int line_count; char **lines = FileOpen("filename", &line_count); // 用实际读取的行数循环,再也不会越界 for(int i = 0 ; i < line_count ; i++) { printf("%s\n", lines[i]); free(lines[i]); // 释放每行的内存 } free(lines); // 释放行数组的内存 return 0 ; } char** FileOpen(char *path, int *out_line_count) { FILE *fileshow = fopen(path, "r"); if(!fileshow) { // 用stderr输出错误信息,更规范 fprintf(stderr, "Error trying to open file %s\n", path); exit(1); } const int max_lines = 100; char** lines = malloc(max_lines * sizeof(char*)); // 检查内存分配是否成功 if (!lines) { perror("Failed to allocate memory for lines"); fclose(fileshow); exit(1); } char buff[1000]; int i = 0 ; while(fgets(buff, sizeof(buff), fileshow)) { // 安全替换换行符:先找到再替换,避免越界 char *newline = strchr(buff, '\n'); if (newline) { *newline = '\0'; } int slen = strlen(buff); // sizeof(char)是1,可省略,同时检查内存分配 char *str = malloc(slen + 1); if (!str) { perror("Failed to allocate memory for line"); // 出错时先释放已分配的内存,避免泄漏 for (int j = 0; j < i; j++) { free(lines[j]); } free(lines); fclose(fileshow); exit(1); } strcpy(str, buff); lines[i] = str; i++; // 超过最大行数时给出提示并终止读取 if (i >= max_lines) { fprintf(stderr, "Warning: File has more than %d lines, truncating\n", max_lines); break; } } *out_line_count = i; // 返回实际读取的行数 fclose(fileshow); // 一定要关闭文件! return lines; }
修复要点说明
- 通过
out_line_count参数传递实际行数,让main函数能正确控制循环范围,彻底避免越界访问。 - 用
strchr安全处理换行符,再也不用担心空行或无换行的最后一行导致内存越界。 - 增加了内存分配失败的检查,出错时会清理已分配的资源,避免内存泄漏。
- 补上了文件关闭和内存释放的代码,养成良好的资源管理习惯。
内容的提问来源于stack exchange,提问作者dabu
相关产品推荐
相关产品推荐

