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

为何我的C语言程序仅打印链表头节点与尾节点?中间节点是否存储?

链表连接问题修复方案

问题分析

你的代码存在两个核心问题:

  • 内存泄漏:在循环的else分支里,nd *p = malloc(sizeof(nd)); 分配了内存,但马上用p = bg;覆盖了指针,这块内存再也无法访问和释放,造成内存浪费。
  • 链表连接逻辑错误:每次添加新节点时,你都直接把bg->next指向新节点,这会把之前设置的bg->next覆盖掉。比如第二次添加节点时,bg->next指向第二个节点;第三次添加时,又把bg->next改成第三个节点,导致第二个节点完全脱离链表,最终遍历只能打印头节点和最后一个节点。

修正后的代码

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

typedef struct node {
    int number;
    struct node *next;
} nd;

nd* create(int num);

int main(void) {
    int n;
    printf("How many numbers do you intend on entering ");
    scanf("%d", &n);
    int num;
    nd* bg = NULL;
    nd* tail = NULL; // 新增尾指针,跟踪链表尾部

    for (int i = 0; i < n; i++) {
        printf("Enter a number: ");
        scanf("%d", &num);
        nd *ls = create(num);
        if (ls == NULL) { // 检查内存分配是否成功
            printf("Memory allocation failed\n");
            return 1;
        }
    
        if (i == 0) {
            bg = ls;
            tail = ls; // 第一个节点既是头也是尾
        }
        else {
            tail->next = ls; // 新节点挂到尾部
            tail = ls; // 更新尾指针到新节点
        }
    }

    // 遍历打印链表
    for (nd *k = bg; k != NULL; k = k->next) {
        printf("%d\n", k->number);
    }

    // 可选:释放链表内存,避免泄漏
    nd* temp;
    while (bg != NULL) {
        temp = bg;
        bg = bg->next;
        free(temp);
    }
}

nd* create(int num) {
    nd *list = malloc(sizeof(nd));

    if (list == NULL) { // 检查内存分配失败
        return NULL; // 返回NULL比0更规范
    }

    list->number = num;
    list->next = NULL;

    return list;
}

关键修正点说明

  1. 新增尾指针tail:不用每次从头遍历找尾部,直接通过尾指针快速添加新节点,效率更高。
  2. 移除无用的malloc:else分支里不再分配多余的内存,避免泄漏。
  3. 完善内存分配检查:在main里检查create函数的返回值,处理内存分配失败的情况。
  4. 规范返回值:create函数内存分配失败时返回NULL,比返回0更符合指针类型的规范。
  5. 新增内存释放逻辑:遍历打印后释放整个链表的内存,避免程序退出后残留内存泄漏(虽然程序退出后系统会回收,但养成好习惯很重要)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 09:18:30