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

C语言遍历链表时空指针检查异常问题排查

链表计数异常问题分析与修复

问题根源

你的代码存在三个核心逻辑错误,导致链表末尾多了一个未初始化的节点:

  1. 提前分配初始节点:程序启动就给first分配内存,若用户直接输入终止值(≤-128),这个节点会成为无意义的空节点,后续遍历会被计入统计。
  2. 强制分配下一个节点:每次输入有效数据后,都会无条件给current->next分配新内存,哪怕之后没有新数据。最后一个有效节点的next会指向一块未初始化的内存,遍历链表时该区域会被当作有效节点,读取到随机值(或0)。
  3. 无效的终止操作:输入终止值时设置current = NULL只是修改了局部指针变量,并未改变链表结构——最后一个有效节点的next依然指向那个多余的空节点。

修复方案

调整链表创建逻辑,仅在输入有效数据时分配节点,确保链表最后一个节点的next指向NULL:

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

int main()
{
    struct record {
        int temperature;
        struct record *next;
    };
    
    struct record *first = NULL;
    struct record *current = NULL;
    
    while (true) {
        int temp;
        printf("Enter measurement: ");
        scanf("%d", &temp);
        
        if (temp <= -128) {
            // 确保链表末尾节点的next为NULL
            if (current != NULL) {
                current->next = NULL;
            }
            break;
        }
        
        // 为当前输入创建新节点
        struct record *new_node = (struct record *)malloc(sizeof(struct record));
        new_node->temperature = temp;
        new_node->next = NULL;
        
        // 链接到链表中
        if (first == NULL) {
            // 处理第一个节点
            first = new_node;
            current = new_node;
        } else {
            current->next = new_node;
            current = new_node;
        }
        printf("Next record created!\n");
    }
    
    // 计算平均值
    current = first;
    double sum = 0.;
    int count = 0;
    while (current != NULL) {
        sum += current->temperature;
        count++;
        printf("%d %d\n", count, current->temperature);
        current = current->next;
    }
    
    // 避免除零错误(无有效输入时)
    if (count > 0) {
        printf("\nAverage of the list values: %.1f", sum / count);
    } else {
        printf("\nNo valid measurements entered.");
    }
    
    // 释放链表内存,避免内存泄漏
    current = first;
    while (current != NULL) {
        struct record *temp_node = current;
        current = current->next;
        free(temp_node);
    }
    
    return 0;
}

修复逻辑说明

  • 延迟节点分配:仅当输入有效数据时才创建新节点,彻底避免初始空节点和末尾多余节点的问题。
  • 明确链表终止:输入终止值时,将最后一个节点的next设为NULL,确保遍历到此处自动停止。
  • 添加边界防护:增加无有效输入时的除零错误处理,同时补充内存释放逻辑避免内存泄漏。

原代码误区解释

你之前尝试用free(current)解决问题,但此时current指向的是最后一个分配的空节点,释放它并不会修改前一个节点的next指针,遍历依然会访问已释放的内存(导致随机值),这属于典型的野指针访问问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 02:27:45