C语言存储GCode文件触发段错误(core dumped)求助
问题原因与解决方法
核心问题:栈溢出触发段错误
你代码里的char full_content[nbr+1][100];是在栈上分配的变长数组(VLA),而程序栈的默认空间通常只有几MB(比如Linux下默认8MB)。当行数超过50000时,数组总大小(比如6万行就占6MB+)加上栈上其他变量会超出栈的容量,直接导致栈溢出,触发segmentation fault错误。
其他代码问题
count_lines函数未检查文件是否成功打开,若文件路径错误或无读取权限,会导致未定义行为。main中手动将nbr设为50000,覆盖了实际统计的文件行数,若文件实际行数更多,会引发数组越界。- 手动循环复制字符串冗余且易出错,直接用
fgets写入目标数组即可完成读取。 - 循环条件
i<=nbr会多执行一次,当文件行数不足时,fgets返回NULL,后续操作会出错。
修正后的代码
#include <stdio.h> #include <stdlib.h> #include <string.h> int count_lines(char name_file[]){ FILE* pFile = fopen(name_file,"r"); if (!pFile) { perror("Failed to open file for counting lines"); return -1; } char content[100]; int nbr = 0; while(fgets(content,100,pFile) != NULL){ nbr++; } fclose(pFile); return nbr; } int main(void) { int nbr = count_lines("Lapin.gcode"); if (nbr == -1) { return 1; } printf("Total lines: %d\n",nbr); FILE* pFile = fopen("Lapin.gcode","r"); if (!pFile) { perror("Failed to open file for reading content"); return 1; } // 用堆内存分配数组,避开栈空间限制 char (*full_content)[100] = malloc(nbr * sizeof(*full_content)); if (!full_content) { perror("Failed to allocate memory"); fclose(pFile); return 1; } // 直接读取每行到数组,简化逻辑 for(int i = 0; i < nbr; i++){ if (fgets(full_content[i], 100, pFile) == NULL) { printf("Warning: Unexpected end of file at line %d\n", i+1); break; } } // 输出存储的内容 for(int i = 0; i < nbr; i++){ printf("%s", full_content[i]); } // 释放堆内存并关闭文件 free(full_content); fclose(pFile); return 0; }
关键修改说明
- 改用堆内存:通过
malloc在堆上分配数组,堆空间远大于栈,支持存储几十万甚至更多行的数据。 - 增加错误检查:对
fopen、malloc、fgets的返回值逐一校验,避免未定义行为。 - 简化读取逻辑:直接用
fgets将每行写入目标数组,删除冗余的手动字符串复制步骤。 - 保留实际行数:不再手动覆盖
nbr,确保数组大小与文件实际行数匹配,避免越界风险。
内容的提问来源于stack exchange,提问作者Maxime Leon
相关产品推荐
相关产品推荐

