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

链表临时节点释放异常:deleteNodeAt函数调用free后失效排查

问题分析与修复方案

嘿,我来帮你揪出这段代码里的问题!你遇到的free(temp)后函数失效的情况,核心是对temp的用途完全搞混了,还错误释放了链表的关键节点,咱们一步步拆解:

1. 先看你代码里的致命错误

  • 你一开始用malloc给temp分配了内存,但之后在if(index==pos-1)时直接把temp = head——这不仅丢了malloc出来的内存(内存泄漏),更糟的是,此时temp指向的是要删除节点的前驱节点(也就是第pos-1个节点),不是你要删掉的目标节点。
  • 当进入index==pos的分支时,你执行了free(temp),这等于把链表的前驱节点给释放了!直接破坏了链表的结构,后续的指针操作自然全乱套,函数也就失效了。

2. 修复后的正确实现

我们需要重新梳理逻辑:找到要删除节点的前驱,单独标记要删除的节点,释放它,再调整链表指针。而且要处理头节点删除的特殊情况,还要做无效输入的判断:

#include <stdlib.h>

// 假设node结构体定义如下(如果你的不是,按需调整)
typedef struct node {
    int data;
    struct node *next;
} node;

void deleteNodeAt(node **head, int pos) {
    // 处理空链表或无效位置(pos从1开始计数的话,pos<=0直接返回)
    if (*head == NULL || pos <= 0) return;

    node *temp = *head;
    // 特殊情况:删除头节点
    if (pos == 1) {
        *head = temp->next;
        free(temp);
        return;
    }

    // 遍历找到要删除节点的前驱(第pos-1个节点)
    for (int index = 1; temp != NULL && index < pos - 1; index++) {
        temp = temp->next;
    }

    // 如果pos超过了链表的实际长度,直接返回(避免访问空指针)
    if (temp == NULL || temp->next == NULL) return;

    // 标记要删除的节点
    node *toDelete = temp->next;
    // 让前驱节点跳过要删除的节点,连接到下一个节点
    temp->next = toDelete->next;
    // 释放要删除的节点
    free(toDelete);
    toDelete = NULL;
}

额外的关键点说明

  • 把参数改成node **head是因为:如果要删除的是头节点,我们需要修改原链表的头指针,传指针的指针才能让修改对外部生效。
  • 增加了对无效位置的判断(比如pos<=0或者pos超过链表长度),避免程序因访问空指针崩溃。
  • 明确区分了前驱节点(temp)和要删除的节点(toDelete),确保只释放真正要删掉的那个节点,不会破坏链表结构。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 12:32:55