C代码运行触发Segfault段错误,请求原因排查
问题分析与修复
核心错误原因
你的代码在main函数构建ascenseur双向链表时,只设置了新节点的etage_prd指针,却没有更新前一个节点的etage_svt指针,导致整个链表的etage_svt链完全断裂——所有节点的etage_svt始终是初始的NULL。
具体来说:
- 当你在main的循环中创建
new_rdch(比如代表B、C的节点)时,仅执行了new_rdch->etage_prd = rdch_prd;,但没有把rdch_prd(前一个节点,比如A)的etage_svt指向新节点。 - 这就导致从
rdch(A节点)开始,所有节点的etage_svt都是NULL,链表的正向遍历根本无法进行。
当调用Ajout_Etage(3)时:
- 初始
etage_up = rdch(指向A节点) - 第一次循环(i=0):
etage_up = etage_up->etage_svt→ 此时A的etage_svt是NULL,etage_up变成NULL - 第二次循环(i=1):尝试访问
NULL->etage_svt,直接触发空指针访问错误,也就是调试器指出的崩溃位置。
修复步骤
1. 修复main函数的链表构建逻辑
在main函数的循环中,创建new_rdch后,添加一行代码更新前一个节点的etage_svt:
rdch_prd = rdch; for (int j = 1; j < 6; j++) { new_rdch = malloc(sizeof(ascenseur)); new_rdch->c = 'A' + j; new_rdch->etage_prd = rdch_prd; new_rdch->etage_svt = NULL; // 新增:将前一个节点的etage_svt指向当前新节点 rdch_prd->etage_svt = new_rdch; rdch_prd = new_rdch; // 后续代码不变... }
这一步会构建完整的双向链表,让每个节点的etage_svt都正确指向下一个节点。
2. 给Ajout_Etage添加边界检查
即使修复了链表,当传入的up值超过链表长度时,etage_up依然会变成NULL,导致后续操作崩溃。可以在循环后添加检查:
ascenseur *Ajout_Etage(int up) { ascenseur *new_Etage = NULL; ascenseur *etage_up = rdch; for (int i = 0; i < up; i++) { // 提前检查,避免空指针访问 if (etage_up == NULL) { printf("错误:up值超过链表长度\n"); return NULL; } etage_up = etage_up->etage_svt; } // 如果循环结束后etage_up为NULL,同样报错 if (etage_up == NULL) { printf("错误:无法找到对应位置的节点\n"); return NULL; } // 后续代码不变... }
其他潜在问题
你在构建chambre循环链表时,逻辑也存在错误:
比如这段代码:
for (i = 2; i < 6; i++) { nouv = malloc(sizeof(chambre)); p->prd = nouv; nouv->num = i; nouv->prd = pre; pre->svt = nouv; pre = nouv; }
最终的循环链表并没有闭合——最后一个节点的svt没有指向头节点p,头节点的svt也没有正确更新。正确的循环链表构建应该在循环结束后,将最后一个节点的svt指向头节点,头节点的prd指向最后一个节点:
// 循环结束后添加: pre->svt = p; p->prd = pre;
这样才能形成完整的循环双向链表。
内容的提问来源于stack exchange,提问作者Youcef Abdelaoui
相关产品推荐
相关产品推荐

