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

为何不使用指针无法在链表中创建新节点?代码问题解析

链表代码无输出问题排查

问题描述

我正在学习链表,编写了如下C语言代码:

#include<stdio.h>
#include<stdlib.h>
 
struct node {
    int value;
    struct node *next;
};
typedef struct node node_t;
 
void printlist(node_t *head){
    //temp is just a pointer to a node; not actually a node
    node_t *temp;
    temp = head;
    printf("%d ", temp->value);
    while (temp != NULL){
        temp = temp->next;
        printf("%d ", temp->value);
         
    }
}
 
node_t create_new_node(int value){
    node_t node;
    node.value = value;
    node.next = NULL;
    return node;        
}
 
int main(){
    node_t *head;
    node_t tmp;
     
    tmp = create_new_node(32);
    head = &tmp;
     
    tmp = create_new_node(87);
    tmp.next = head;
    head = &tmp;
    
    printlist(head);
     
    return 0;
}

但运行后无任何输出。我的疑问是:为何此处的create_new_node函数无法正常工作?该函数内的node不是静态分配的吗?我知道使用指针可以解决问题,但想了解当前代码失效的原因,此前尝试使用malloc但也未成功。感谢解答!

问题分析与解答

1. 关于create_new_node函数的误解

你提到的“静态分配”是错误的:函数内的node_t node;是栈上的自动局部变量,并非静态分配(静态分配需要在变量前加static关键字)。不过这个函数本身的逻辑没问题——它返回结构体的副本,调用时会把局部变量的内容完整拷贝到调用方的变量(比如main里的tmp)中,所以函数本身不是导致无输出的直接原因。

2. main函数中链表构建的逻辑错误

你的链表构建过程完全破坏了节点结构:

  • 第一次执行tmp = create_new_node(32); head = &tmp;时,head指向tmp的内存地址,此时tmp存储着值为32的节点数据。
  • 第二次执行tmp = create_new_node(87);时,同一个tmp变量的内存被新的节点数据覆盖,原来存储32的内容彻底消失。后续tmp.next = head;中,head仍然指向tmp的地址(因为tmp是同一个变量,地址从未改变),这就导致新节点的next指针指向了自己,形成了一个循环链表,而非你预期的两个节点的链表。

3. printlist函数的致命错误

这是程序无输出的直接原因:
函数开头先打印temp->value(此时temp是head,没问题),然后进入循环:

while (temp != NULL){
    temp = temp->next;
    printf("%d ", temp->value);
}

当temp指向最后一个节点时,temp->next是NULL,执行temp = temp->next;后,temp变成NULL,此时再访问temp->value就是空指针解引用,触发C语言的未定义行为——程序会直接崩溃,根本来不及输出任何内容(或者输出乱码后立即终止)。

正确的printlist写法应该是:

void printlist(node_t *head){
    node_t *temp = head;
    while (temp != NULL){
        printf("%d ", temp->value);
        temp = temp->next;
    }
}

4. 关于malloc的正确用法

你之前用malloc没成功,大概率是写法错误。正确的节点创建函数应该返回指针,从堆上分配内存:

node_t* create_new_node(int value){
    node_t *node = malloc(sizeof(node_t));
    // 必须检查malloc是否成功,避免空指针
    if(node == NULL){
        perror("malloc failed");
        exit(EXIT_FAILURE);
    }
    node->value = value;
    node->next = NULL;
    return node;
}

对应的main函数链表构建逻辑:

int main(){
    node_t *head = NULL;
    // 创建第一个节点
    node_t *new_node = create_new_node(32);
    head = new_node;
    // 创建第二个节点并链接到头部
    new_node = create_new_node(87);
    new_node->next = head;
    head = new_node;
    
    printlist(head);
    
    // 记得释放堆内存,避免泄漏
    node_t *temp = head;
    while(temp != NULL){
        node_t *next = temp->next;
        free(temp);
        temp = next;
    }
    return 0;
}

这样每个节点都在堆上独立分配,不会被覆盖,链表结构也能正常构建。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 10:55:14