C语言嵌套链表读取文件进入car_filetolist函数触发段错误求助
问题排查与修复
核心触发段错误的原因
- 死循环导致栈溢出:
getcarall函数的循环逻辑完全错误:你初始化temp = head1,循环条件写的是while(temp != NULL),但整个循环体里从来没有修改过temp的值,导致循环永久执行,不断调用strcat(dest, head1->data)往只有100字节的dest数组里拼接内容,很快就会发生栈溢出,破坏栈结构,调用car_filetolist时直接触发段错误。 - 未初始化变量+类型错误:
car_filetolist和get_datefromFile里的flag变量都是char类型,未初始化就直接判断while(flag != EOF),未初始化的变量值是随机的,会导致循环逻辑完全异常。另外getc()返回值是int类型,EOF的值是-1,用有符号char存可能会出现截断匹配错误,用无符号char根本存不下-1,判断永远不会成立。 fopen未做空判断:car_filetolist里调用fopen(dest, "r")后没有判断返回值是否为NULL,如果对应日期的文件不存在、路径拼写错误、权限不足,file指针就是NULL,后续fscanf读取NULL指针会直接触发段错误。fscanf无长度限制:所有用fscanf("%s", 缓冲区)的地方都没有限制读取长度,一旦文件里的字段超过你申请的缓冲区大小(比如targa超过9字符、nome超过11字符),会发生堆溢出,破坏内存结构触发段错误。
其他隐藏逻辑缺陷
- 链表创建逻辑冗余:两个读取链表的函数都是先申请一个节点再读数据,哪怕文件已经读完或者为空,都会生成一个内容为垃圾值的无效节点,导致链表最后多一个无效节点。
- 内存泄漏风险:所有的
malloc都没有做返回值判断,申请失败会导致后续操作空指针。
修复建议
- 修正
getcarall的循环逻辑:要么把循环条件改成while(head1 != NULL),要么循环体里每次修改temp的值作为遍历指针,避免死循环。 - 把所有
flag变量改成int类型,并且初始化:int flag = 0;,循环判断逻辑调整为先读再判断,避免生成多余节点。 - 所有
fopen调用后都加空判断,示例:
file = fopen(dest, "r"); if (file == NULL) { perror("打开文件失败"); return NULL; }
- 调整
fscanf的写法,限制读取长度,比如targa申请了10字节,就写fscanf(file, "%9s", head->targa),留1字节存字符串结束符\0。 - 路径拼接前检查总长度,或者把
dest数组放大到足够的大小,避免栈溢出。 - 调整链表创建逻辑,先判断文件是否有数据,再申请节点,避免生成无效节点。
内容的提问来源于stack exchange,提问作者Alessandro Romeo
相关产品推荐
相关产品推荐

