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

为何C语言链表删除尾节点函数未置previousNode->next为NULL会出错?

链表尾节点删除的异常问题分析

问题代码

Node* deleteAtTail(Node* head)
{
    if (head == NULL)                               /* If List is empty... */
    {
        return NULL;
    }
    else                                            /* If List has 1 item... */
    if (head -> next == NULL)
    {
        free(head);
        return NULL;
    }
    else
    {
        Node* currentNode = head;                   /* Traversal Pointer */
        Node* previousNode = NULL;                  /* Traversal Pointer */

        while(currentNode -> next != NULL)
        {
            previousNode = currentNode;             /* Move up previous node */
            currentNode = currentNode -> next;      /* Move up current node */
        }

        previousNode -> next = NULL;                /* Make previousNode the new tail */
        free(currentNode);                          /* Delete currentNode pointer */
        return head;
    }
}

用户问题

若注释掉previousNode -> next = NULL;这行代码,程序会陷入无限循环。

请问这是为什么?我认为head及其链表并未被修改,只是复制给了currentNode指针,且我返回的是未改动的链表。previousNode和currentNode都在函数作用域内,为何不设置previousNode的next指针为NULL程序就会失效?

问题解析

  • 指针操作的是原链表内存:currentNode和previousNode是函数内的局部指针,但它们指向的是堆上的链表节点实际内存,不是链表的副本。修改previousNode->next就是直接修改原链表的节点内容,并非操作所谓的“副本”。
  • 释放内存后留下野指针:注释掉previousNode->next = NULL后,原尾节点被free释放,但倒数第二个节点的next指针还指着这块已被释放的内存。这块内存的内容是不确定的,属于野指针范畴。
  • 无限循环的触发逻辑:如果后续有遍历链表的操作(比如再次调用删除尾节点、打印链表),当遍历到倒数第二个节点时,next指向的野指针内存里的值可能不是NULL,导致遍历的while循环条件currentNode->next != NULL永远成立,直接陷入无限循环。
  • 返回head不解决问题:head确实没被修改,但链表的结构已经被破坏——倒数第二个节点的next是非法指针,返回的head只是指向一个有缺陷的链表起始地址而已。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 04:00:10