读取整数CSV文件的C程序触发Segmentation Fault(段错误)的原因?
段错误原因排查及修复
核心问题:未初始化的局部变量
read函数中的i和j是局部变量,C语言中局部变量默认不会被初始化为0,它们的初始值是栈上的随机垃圾值。当你第一次执行B[i][j++]或B[i++][j]时,i和j的随机值大概率会超出数组B的索引范围(数组仅DIM×DIM=2×2的空间),导致越界写入非法内存。这会破坏栈结构或其他内存区域,当main函数中的循环尝试访问B数组时,就触发了段错误。
其他致命问题
除了未初始化变量,代码还有几个必须修复的问题:
- 循环条件错误:原代码的
while ((c = getc(fp)))会把EOF(值为-1)当作“真”继续循环,正确写法应为while ((c = getc(fp)) != EOF),确保读取到文件末尾时终止循环。 - 数字判断逻辑写反:原代码中
'0' >= c || c <= '9'的条件完全错误,应改为c >= '0' && c <= '9',否则会把非数字字符(比如逗号、换行)当成数字处理,计算出错误数值。 - 文件末尾处理冗余:循环条件已判断
!= EOF,无需再在循环内处理c == EOF的情况,否则会导致逻辑混乱。
修复后的完整代码
#include <stdio.h> #define DIM 2 void read(char path[], long long (*B)[DIM]); int main(int argc, char *argv[]) { long long B[DIM][DIM]; read("test.csv", B); for (int i = 0; i < DIM; i++) for (int j = 0; j < DIM; j++) printf("%lld\n", B[i][j]); return 0; } void read(char path[], long long (*B)[DIM]) { int i = 0, j = 0; // 初始化索引变量 int c, sign = 1; long long number = 0; FILE *fp = fopen(path, "r"); if (fp) { while ((c = getc(fp)) != EOF) // 修正循环条件 if (c == '-') { sign = -1; } else if (c == ',') { B[i][j++] = sign * number; sign = 1; number = 0; } else if (c == '\n') { B[i++][j] = sign * number; j = 0; sign = 1; number = 0; } else if (c >= '0' && c <= '9') { // 修正数字判断条件 number = (number * 10) + (c - '0'); } // 处理文件最后一行无换行的情况 if (j < DIM && number != 0) { B[i][j] = sign * number; } fclose(fp); } else { printf("File %s not found.\n", path); } }
内容的提问来源于stack exchange,提问作者scribe
相关产品推荐
相关产品推荐

