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

LeetCode 206反转链表代码出现heap-use-after-free错误求助

LeetCode 206. Reverse Linked List 堆使用后释放错误分析

在解决LeetCode 206. Reverse Linked List(给定单链表的head节点,反转该链表并返回反转后的链表)问题时,编写了如下代码:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    ListNode* reverseList(ListNode* head) {
        vector<ListNode*> addrs;
        ListNode* cur=head;
        if(cur==NULL||cur->next==NULL) return cur;

        // storing all addrs in sequence
        while(cur!=NULL)
        {
            addrs.push_back(cur);
            cur=cur->next;
        }
        // reversing process
        for(int i=addrs.size()-1;i>0;i--)
        {
            addrs[i]->next=addrs[i-1];
        }
        return addrs[addrs.size()-1];
    }
};

测试时触发错误:

ERROR: AddressSanitizer: heap-use-after-free

错误原因分析

错误和vector无关,核心问题是反转后未处理原链表头节点的next指针:

  • 反转操作仅设置了从最后一个节点到第二个节点的next指向,但原链表的头节点(即addrs[0])的next仍指向原第二个节点,导致链表形成循环引用。比如原链表为1->2->3,反转后变为3->2->1,但1的next还是指向2,最终链表成了3->2->1->2->...的环。
  • LeetCode的测试框架在遍历或回收链表内存时,会因循环引用出现无限遍历或重复访问已释放内存的情况,触发AddressSanitizer的heap-use-after-free报错。

修复方案

在反转循环结束后,添加一行代码将原头节点的next置空,断开环结构:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    ListNode* reverseList(ListNode* head) {
        vector<ListNode*> addrs;
        ListNode* cur=head;
        if(cur==NULL||cur->next==NULL) return cur;

        // storing all addrs in sequence
        while(cur!=NULL)
        {
            addrs.push_back(cur);
            cur=cur->next;
        }
        // reversing process
        for(int i=addrs.size()-1;i>0;i--)
        {
            addrs[i]->next=addrs[i-1];
        }
        // 断开原头节点的next,避免循环引用
        addrs[0]->next = nullptr;
        return addrs[addrs.size()-1];
    }
};

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 00:47:30