C语言实现单链表:头节点不存在时创建的问题排查
单链表创建头节点的问题分析与解决
首先我先把你没写完的代码补全(看起来是输入到一半中断了),完整的append函数大概是这样:
#include <stdio.h> #include <stdlib.h> typedef struct NODE{ int value; struct NODE* next; }node; int append(node* head, int val){ if(head == NULL){ printf("Head is NULL"); head = malloc(sizeof(node)); if(head == NULL){ return EXIT_FAILURE; } head->value = val; head->next = NULL; } else { printf("Head is not NULL"); while(head->next != NULL){ head = head->next; } node* new_node = malloc(sizeof(node)); if(new_node == NULL){ return EXIT_FAILURE; } new_node->value = val; new_node->next = NULL; head->next = new_node; } return EXIT_SUCCESS; }
问题核心:C语言的值传递特性
你遇到的问题本质是:C语言里函数参数是按值传递的。当你把head指针传给append函数时,函数内部会创建一个head的副本——你在函数里修改这个副本(比如用malloc给它分配内存),并不会改变外部原来的head指针的值。也就是说,当你调用append(NULL, 10)之后,外部的head依然是NULL,根本没被更新。
两种解决方案
方案1:使用二级指针(指针的指针)
让函数接收一个node**类型的参数,这样就能直接修改外部的指针变量:
int append(node** head, int val){ if(*head == NULL){ printf("Head is NULL\n"); *head = malloc(sizeof(node)); if(*head == NULL){ return EXIT_FAILURE; } (*head)->value = val; (*head)->next = NULL; } else { printf("Head is not NULL\n"); node* current = *head; while(current->next != NULL){ current = current->next; } node* new_node = malloc(sizeof(node)); if(new_node == NULL){ return EXIT_FAILURE; } new_node->value = val; new_node->next = NULL; current->next = new_node; } return EXIT_SUCCESS; }
调用的时候要传指针的地址:
int main(){ node* head = NULL; append(&head, 5); append(&head, 10); // 后续遍历、释放内存等操作... return 0; }
方案2:让函数返回更新后的头指针
另一种方式是让append函数返回新的头节点指针,外部接收这个返回值来更新head:
node* append(node* head, int val){ if(head == NULL){ printf("Head is NULL\n"); node* new_head = malloc(sizeof(node)); if(new_head == NULL){ printf("Malloc failed\n"); return NULL; } new_head->value = val; new_head->next = NULL; return new_head; } else { printf("Head is not NULL\n"); node* current = head; while(current->next != NULL){ current = current->next; } node* new_node = malloc(sizeof(node)); if(new_node == NULL){ printf("Malloc failed\n"); return head; // 返回原头指针,避免丢失链表 } new_node->value = val; new_node->next = NULL; current->next = new_node; return head; } }
调用方式:
int main(){ node* head = NULL; head = append(head, 5); head = append(head, 10); // 后续遍历、释放内存等操作... return 0; }
额外小建议
- 记得在使用完链表后,要遍历链表释放所有节点的内存,避免内存泄漏。
- 你已经给
malloc加了错误判断,这一点做得很到位!
内容的提问来源于stack exchange,提问作者semmelbroesl
相关产品推荐
相关产品推荐

