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

单链表删除首节点出现随机数值问题求助

单链表删除首节点出现随机值问题分析

问题描述

编写单链表示例程序,流程为:用户输入节点数量并填充数据,随后输入节点序号删除对应节点。删除非首节点功能正常,但删除首节点(输入序号1)时会出现随机数值。

问题代码

NodePointer deleteNode(NodePointer head,int number)
{
    NodePointer ptrNode;
    NodePointer ptrNodePrev;
    int count;
    if(head == NULL)
    {
        printf("There is no element at list");
    }
    if(number == 1)
    {
       ptrNodePrev=head;
       head=head->next;
       free(ptrNodePrev);
    }
    else{
        ptrNode=head;
        while(ptrNode->next != NULL && count+1 != number){
            count++;
            ptrNodePrev=ptrNode;
            ptrNode=ptrNode->next;
        }
        ptrNode=ptrNode->next;
        printf("Node: %d-%d-%d - %s",ptrNodePrev->next->x.year,
                                      ptrNodePrev->next->x.month,
                                      ptrNodePrev->next->x.day,
                                      ptrNodePrev->next->x.event);
        printf("Successfully deleted");
        free(ptrNodePrev->next);
        ptrNodePrev->next=ptrNode;
    }
    return head;
}

错误原因分析

  1. 调用方未正确更新链表头指针
    删除首节点时,函数内部已将head指向原首节点的下一个节点,并释放了原首节点内存。但如果调用时未将返回的新head赋值给原链表头指针(例如写成deleteNode(head, 1)而非head = deleteNode(head, 1)),原head指针仍指向已释放的内存,后续访问该指针会读取到随机垃圾值,这是导致问题的核心原因。

  2. 代码结构存在逻辑漏洞

    • 两个独立的if语句导致空链表场景下的非法访问:当head == NULL时,第一个if执行提示后,会继续进入number == 1的判断,此时访问head->next会触发崩溃。
    • 正确的结构应将空链表判断作为前置检查并提前返回,后续用if-else区分首节点与非首节点的删除逻辑。
  3. 未初始化的count变量
    else块中的count未初始化,初始值为随机值,导致while循环条件count+1 != number不可靠,可能引发循环提前终止或过度遍历,属于潜在bug。

修复建议

  • 强制更新链表头指针:调用函数时必须接收返回的新head,示例:
    head = deleteNode(head, 1);
    
  • 调整代码结构并完善逻辑:
    NodePointer deleteNode(NodePointer head,int number)
    {
        NodePointer ptrNode;
        NodePointer ptrNodePrev;
        int count = 1; // 初始化计数,对应节点序号起始值1
    
        // 空链表前置检查
        if(head == NULL)
        {
            printf("There is no element at list");
            return head;
        }
    
        // 删除首节点
        if(number == 1)
        {
            ptrNodePrev = head;
            head = head->next;
            // 输出删除节点信息
            printf("Node: %d-%d-%d - %s", ptrNodePrev->x.year,
                                          ptrNodePrev->x.month,
                                          ptrNodePrev->x.day,
                                          ptrNodePrev->x.event);
            printf("Successfully deleted");
            free(ptrNodePrev);
        }
        // 删除非首节点
        else
        {
            ptrNode = head;
            // 遍历寻找目标节点
            while(ptrNode != NULL && count != number)
            {
                count++;
                ptrNodePrev = ptrNode;
                ptrNode = ptrNode->next;
            }
    
            // 检查是否找到目标节点
            if(ptrNode == NULL)
            {
                printf("Node not found");
                return head;
            }
    
            // 执行删除操作
            ptrNodePrev->next = ptrNode->next;
            printf("Node: %d-%d-%d - %s", ptrNode->x.year,
                                          ptrNode->x.month,
                                          ptrNode->x.day,
                                          ptrNode->x.event);
            printf("Successfully deleted");
            free(ptrNode);
        }
    
        return head;
    }
    
  • 初始化所有局部变量:避免未初始化变量导致的不可预测行为。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 10:55:50