如何保存双向链表尾节点指针?删除尾节点时段错误怎么修复?
修复双向链表按位置删除函数的段错误问题
咱们来一步步拆解你代码里的问题,然后给出靠谱的修复方案:
核心问题分析
删除尾节点时的空指针访问
当你删除最后一个节点时,temp->next是NULL,这时候你执行temp->next->prev = prev,相当于直接访问NULL的prev成员,这必然会触发段错误。尾节点指针更新错误
你写的&last = temp->next;完全是错误的用法——last是二级指针,要修改它指向的尾节点变量,应该用*last = ...,而不是取last的地址赋值。未处理删除第一个节点的边界情况
如果要删除的是第一个节点(position=0),你的代码里prev还没被赋值,这时候prev是野指针,执行prev->next会直接崩溃;如果这是链表唯一的节点,还需要同时把list和*last都设为NULL。
修复后的完整代码
node* deleteByPos(node* list, node** last, int position) { int c = 0; node* temp = list; node* prev = NULL; // 空链表的情况 if (temp == NULL) { printf("No nodes available to delete\n\n"); return list; } // 找到要删除的节点 while (temp != NULL && c != position) { prev = temp; temp = temp->next; c++; } // 位置超出链表长度 if (temp == NULL) { printf("Reached end of list, position not available\n\n"); return list; } // 情况1:删除的是第一个节点 if (prev == NULL) { list = temp->next; // 如果删除后还有节点,更新新头节点的prev if (list != NULL) { list->prev = NULL; } else { // 链表删空了,尾节点也要设为NULL *last = NULL; } } // 情况2:删除的是最后一个节点 else if (temp->next == NULL) { prev->next = NULL; *last = prev; // 更新尾节点为当前节点的前驱 } // 情况3:删除中间节点 else { prev->next = temp->next; temp->next->prev = prev; } // 释放节点内存 free(temp); return list; }
关键修改说明
- 初始化
prev为NULL,这样可以直接判断是否要删除第一个节点 - 拆分三种删除场景:头节点、尾节点、中间节点,分别处理,彻底避免空指针访问
- 正确更新尾节点指针:删除尾节点时把
*last设为prev;链表删空时把*last设为NULL - 删除头节点时,同步更新链表头指针
list,并处理链表为空的边界情况
内容的提问来源于stack exchange,提问作者vkygul
相关产品推荐
相关产品推荐

