C语言实现链表ADT报Segmentation fault (core dumped)错误如何解决
问题定位
- 核心触发点是空指针解引用:
init函数执行后,链表的head指针被赋值为NULL,同时length被设置为10。调用print函数时,循环第一次执行就会对空指针p(初始值等于head也就是NULL)执行(*p).num操作,访问非法内存直接触发段错误。 - 逻辑设计错误:
List结构体的length字段被用作最大容量,但没有额外字段记录当前链表实际存储的节点数,空链表无任何节点的情况下,print函数强制遍历length次,完全不符合链表实际状态。 - 遍历逻辑漏洞:
print函数没有对遍历指针做非空判断就直接解引用,哪怕后续插入了部分节点,只要实际节点数小于length,依然会触发空指针访问。
修复方案
快速临时修复(仅避免段错误,不调整整体逻辑)
直接修改print函数的循环判断条件,增加指针非空校验:
void print(List L) { int i; NodeType *p; printf("List is: "); for (i=0, p=L.head; i<L.length && p != NULL; i++, p=p->next) { // 增加p != NULL判断 printf(" %d ", p->num); } putchar('\n'); }
修改后空链表调用print会直接输出List is: ,不会触发崩溃。
规范修复(调整链表ADT逻辑)
- 修改
list.h中的List结构体定义,区分最大容量和实际节点计数:
typedef struct { int max_size; // 存储链表最大容量 int cur_size; // 存储当前实际存储的节点数 NodeType *head; } List; // 补充add函数声明 void add(List *L, int val);
- 修改
list.c中的init函数初始化逻辑:
void init(int maxSize, List *L) { L->max_size = maxSize; L->cur_size = 0; // 初始无节点,实际计数为0 L->head = NULL; }
- 修复
print函数的遍历逻辑,直接以指针非空作为遍历终止条件:
void print(List L) { NodeType *p = L.head; printf("List is: "); while (p != NULL) { printf(" %d ", p->num); p = p->next; } putchar('\n'); }
- 补充实现
add插入函数,插入时更新实际节点计数:
void add(List *L, int val) { // 容量判断 if (L->cur_size >= L->max_size) { printf("链表已达最大容量,插入失败\n"); return; } // 申请新节点内存 NodeType *new_node = (NodeType*)malloc(sizeof(NodeType)); if (new_node == NULL) { printf("内存申请失败\n"); return; } new_node->num = val; // 头插法插入节点,可根据需要改为尾插 new_node->next = L->head; L->head = new_node; L->cur_size++; }
修改后放开main函数中add调用的注释即可正常插入、遍历链表。
内容的提问来源于stack exchange,提问作者Cheetos
相关产品推荐
相关产品推荐

