C++链表偶数节点提取程序异常:指针错误与段错误排查
链表提取偶数节点问题分析与修复
问题1:new_list_head指向新链表最后一个元素的原因
你大概率是在构建新链表时,没有固定头指针的初始位置。比如一开始new_list_head和current都指向空,找到第一个偶数节点时,没有把new_list_head固定为这个节点,而是每次添加新节点都让new_list_head跟着current往后移,最后自然指向了最后一个节点。
问题2:段错误的原因
段错误通常是访问了非法内存,常见触发场景:
- 原链表遍历过程中没写
head = head->next,导致死循环,最终访问到野指针; - 新链表的尾节点
next没有设为NULL,print时循环无法终止,越界访问; - 当原链表没有偶数节点时,
new_list_head为空,后续操作中直接访问了空指针的成员(比如new_list_head->val)。
修复后的代码示例
#include <iostream> using namespace std; struct ListNode { int val; ListNode* next; ListNode(int x) : val(x), next(NULL) {} }; ListNode* extractEvenNodes(ListNode* head) { ListNode* new_list_head = NULL; ListNode* current = NULL; while (head != NULL) { if (head->val % 2 == 0) { ListNode* new_node = new ListNode(head->val); if (new_list_head == NULL) { // 第一个偶数节点,同时作为新链表的头和当前遍历节点 new_list_head = new_node; current = new_node; } else { // 后续节点挂载到current后,只移动current current->next = new_node; current = new_node; } } head = head->next; // 必须移动原链表指针,否则死循环 } // 确保新链表尾节点next为空,避免野指针 if (current != NULL) { current->next = NULL; } return new_list_head; } void print_list(ListNode* head) { while (head != NULL) { cout << head->val << " "; head = head->next; } cout << endl; } int main() { // 测试链表:1->2->3->4->5->6 ListNode* head = new ListNode(1); head->next = new ListNode(2); head->next->next = new ListNode(3); head->next->next->next = new ListNode(4); head->next->next->next->next = new ListNode(5); head->next->next->next->next->next = new ListNode(6); cout << "原链表:"; print_list(head); ListNode* even_list = extractEvenNodes(head); cout << "偶数节点链表:"; print_list(even_list); // 实际项目中需手动释放链表内存,此处简化处理 return 0; }
关键修复点说明
- 固定头指针:首次创建偶数节点时,将
new_list_head和current同时指向该节点,后续只移动current,保证头指针始终指向新链表第一个元素; - 终止循环:遍历原链表时必须执行
head = head->next,避免死循环; - 清理尾节点:新链表最后一个节点的
next设为NULL,确保print_list的循环能正常终止; - 空指针判断:处理新链表时先检查
current是否为空,避免空指针赋值。
内容的提问来源于stack exchange,提问作者mndl
相关产品推荐
相关产品推荐

