读取student.txt存入链表时出现段错误,无法打印内容,求代码排查建议
代码段错误问题排查
所有触发段错误的硬伤逐一列明:
strdup参数完全用错:strdup的入参是「需要被复制的字符串首地址」,不是内存分配长度。你写的node->name = strdup(128)、node->number = strdup(8)本质是把整数128、8当成内存地址去读,直接触发非法内存访问,是段错误的核心原因。正确用法是直接传入收到的name、number入参,让strdup自动在堆上分配适配长度的内存完成字符串复制,完全匹配Student结构体里char *的设计。- 语法结构错位:你把
print函数的完整实现直接写在add函数的函数体内部,C语言标准不支持函数嵌套定义,哪怕依赖编译器扩展编译通过,函数作用域也是完全错误的,根本无法被main函数正常调用。 - 局部变量存不住链表状态:你在
add函数内定义的Student *current, *head是函数级局部变量,每次调用add时这两个变量的初始值都是随机的,根本无法持久存储链表头、链表尾的位置。同时print函数里跨函数使用局部变量head,本身就是非法的内存访问。 - add函数返回值逻辑失效:add函数从头到尾没有修改传入的
list参数,最后却直接return list;——main函数里每次赋值拿到的list永远是初始的NULL,完全持有不到新建的节点地址,后续打印时访问NULL指针必然崩溃。 - 双向链表指针缺失:结构体里定义了
previous前驱指针,但add实现时完全没有给新节点的前驱、原尾节点的后继做正确赋值,哪怕前面的问题修复,反向遍历依然会触发野指针访问。 - 无文件打开合法性校验:
fopen("student.txt", "r")之后没有判断返回值是否为NULL,一旦文件路径不对、权限不足,后续直接用无效的FILE指针做fscanf操作,也是常见的段错误诱因。 - print函数逻辑错位:print函数的形参是传入的链表头,但循环逻辑完全没使用这个参数,反而用不存在的局部head做遍历,逻辑完全走偏。
正确实现的核心调整点:
- 字符串赋值直接写
node->name = strdup(name);、node->number = strdup(number);,不需要手动指定malloc长度,strdup会自动完成内存分配和内容复制- 完全靠add的入参list维护链表状态:如果list为NULL,直接返回新建节点作为链表头;如果不为空,遍历到链表尾部,将新节点接到尾部,同时给新节点的
previous赋值为原尾节点- print函数独立定义,直接基于传入的list参数做正向遍历,不需要额外定义局部head变量
- fopen之后第一行增加判空逻辑:
if (in == NULL) { perror("打开student.txt失败"); return 1; }
内容的提问来源于stack exchange,提问作者Walter
相关产品推荐
相关产品推荐

