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

LeetCode第142题(环形链表II)出现heap-use-after-free错误如何修复?

修复LeetCode 142题《环形链表II》的heap-use-after-free错误

问题根源

你的代码存在三个核心问题:

  • 返回类型不匹配:函数声明返回struct ListNode*,但你返回了head->val(整数)和-1(整数),类型不匹配会触发未定义行为,间接导致内存错误。
  • 堆内存访问违规:当你free(flag)后,之前被修改为指向flag的节点next指针,全部变成了指向已释放的堆内存。虽然此时执行了return,但这种写法存在内存安全风险。
  • 逻辑错误:判断条件head->next == flag无法正确识别环入口——环入口节点的next指向环内节点,而非你创建的flag,导致环检测逻辑失效。
  • 破坏输入链表:修改节点的val和next指针会破坏原链表结构,这在算法题中是不被允许的。

推荐修复方案:快慢指针法

这是环形链表问题的最优解法,无需修改原链表,无内存安全问题:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
struct ListNode *detectCycle(struct ListNode *head) {
    if (!head || !head->next) return NULL;

    struct ListNode *slow = head, *fast = head;
    // 检测环是否存在
    while (fast && fast->next) {
        slow = slow->next;
        fast = fast->next->next;
        if (slow == fast) break;
    }
    // 无环直接返回
    if (!fast || !fast->next) return NULL;
    // 寻找环入口:slow重置到head,快慢指针同速前进,相遇点即为入口
    slow = head;
    while (slow != fast) {
        slow = slow->next;
        fast = fast->next;
    }
    return slow;
}

原思路的最小修正(不推荐)

如果一定要用标记节点的思路,需修正返回类型、调整环检测逻辑,同时避免提前释放内存:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
struct ListNode *detectCycle(struct ListNode *head) {
    struct ListNode *flag = malloc(sizeof(struct ListNode));
    struct ListNode *curr = head;

    while (curr) {
        if (curr == flag) { // 当前节点已被标记,即为环入口
            free(flag);
            return curr;
        }
        struct ListNode *next = curr->next;
        curr->next = flag; // 标记当前节点
        curr = next;
    }

    free(flag);
    return NULL;
}

注意:此方法会破坏原链表结构,不符合算法题的常规要求,仅作思路参考。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 05:25:18