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

C语言链表头传递函数问题:为何我的代码与视频示例行为不同?

C语言链表初始化后print_ll中next指针非NULL的问题分析

你的问题根源不在头指针的传递方式上,不需要传递头指针的指针,核心bug出在init_ll函数的内存分配逻辑上:

在init_ll里,你声明的new_node是栈上的局部变量。当函数执行完毕返回时,栈上的局部变量会被操作系统回收,这块内存会被后续的函数调用(比如print_ll)覆盖。你返回的&new_node是一个指向已经被释放的栈内存的指针,属于野指针。

这就解释了为什么:

  • main函数里第一次打印head->value和head->next看似正常——此时栈内存还没被覆盖;
  • 进入print_ll函数后,栈内存被新的函数栈帧覆盖,tmp->next读到了垃圾值,而非预期的NULL。

视频里的代码能正常运行,是因为它大概率用了堆内存分配(通过malloc),堆上的内存不会随函数返回被释放,指针能一直有效。

修正后的init_ll函数

#include <stdio.h>
#include <stdlib.h> // 引入malloc和exit的头文件

typedef struct node_t{
    int value;
    struct node_t *next;
}node_t;

node_t *init_ll(int value) {
    // 用malloc在堆上分配节点内存
    node_t *new_node = malloc(sizeof(node_t));
    // 必须检查malloc是否成功
    if (new_node == NULL) {
        perror("malloc failed");
        exit(EXIT_FAILURE);
    }
    new_node->value = value;
    new_node->next = NULL;
    return new_node;
}

void print_ll(node_t *head) {
    node_t *tmp = head;
    printf("first node val: %d and next pointer %p\n", tmp->value, tmp->next);
    /*
    while (tmp != NULL) {
        printf("%d - ", tmp->value);
        tmp = tmp->next;
    }
    */
    printf("\n");
}

int main() {
    node_t *head = init_ll(5);

    printf("n1.value = %d\n", head->value);
    printf("n1.next ptr = %p\n", head->next);

    print_ll(head);

    // 释放堆内存,避免泄漏
    free(head);
    return 0;
}

额外注意

使用堆内存分配的链表,在程序结束前要记得逐个释放节点,避免内存泄漏。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 03:40:45