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

C语言链表delete_min函数堆内存错误:释放节点后仍异常

堆内存错误修复:delete_min函数的前驱指针逻辑问题

打印“3rd round”后出现指针异常,虽已在delete_min中执行free(min_node)并将其置为NULL,但堆内存错误仍持续发生——核心问题出在delete_min函数中寻找最小值节点时的前驱指针跟踪逻辑完全错误,而非内存释放操作。

错误根源分析

原delete_min函数的搜索循环中,prev变量的更新逻辑混乱:

  • 当发现更小的节点时,prev = (prev == NULL)? head : prev->link 无法正确指向最小值节点的前驱,导致后续删除操作时,prev指向的并非目标节点的前一个节点,进而破坏链表结构,引发野指针访问或内存非法操作。

修复后的delete_min函数代码

ListNode* delete_min(ListNode* head)
{
    if (head == NULL) { 
        printf("List is empty.\n");
        return NULL;
    }

    ListNode* min_node = head;
    ListNode* prev_min = NULL; // 专门跟踪最小值节点的前驱
    ListNode* current = head;
    ListNode* prev_current = NULL;

    // 遍历链表,寻找最小值节点及其前驱
    while (current != NULL) {
        if (current->data.point < min_node->data.point) {
            min_node = current;
            prev_min = prev_current; // 更新为当前节点的前驱
        }
        prev_current = current;
        current = current->link;
    }

    // 删除最小值节点
    if (min_node == head) {
        // 处理头节点删除
        head = head->link;
    }
    else {
        // 通过前驱节点跳过min_node,维护链表完整性
        prev_min->link = min_node->link;
    }
    printf("OUT: %s (%d)\n\n", min_node->data.name, min_node->data.point);
    free(min_node);

    return head;
}

修复说明

  1. 拆分原混乱的prev变量为prev_min和prev_current,分别跟踪最小值节点的前驱和当前遍历节点的前驱,逻辑清晰无歧义。
  2. 遍历过程中,每当找到更小的节点,直接将prev_min赋值为当前节点的前驱prev_current,确保删除时能正确定位到目标节点的前一个节点。
  3. 删除操作时,头节点直接更新head指针;非头节点通过prev_min->link跳过min_node,保证链表结构不被破坏,从根源避免野指针和内存错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 10:07:47