You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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;
}

关键修复点说明

  1. 固定头指针:首次创建偶数节点时,将new_list_head和current同时指向该节点,后续只移动current,保证头指针始终指向新链表第一个元素;
  2. 终止循环:遍历原链表时必须执行head = head->next,避免死循环;
  3. 清理尾节点:新链表最后一个节点的next设为NULL,确保print_list的循环能正常终止;
  4. 空指针判断:处理新链表时先检查current是否为空,避免空指针赋值。

内容的提问来源于stack exchange,提问作者mndl

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 06:30:56