C语言实现Linked_list_builder函数构建、返回及遍历打印链表
原代码错误定位
- 语法疏漏:
main函数中return 0语句末尾缺少分号,无法通过编译。 scanf传参错误:scanf要求传入待写入变量的内存地址,原代码scanf("%d",list->data)直接传入结构体成员的值,会触发非法内存访问导致程序崩溃,正确写法应为传入变量地址。- 链表构建逻辑错误:原代码一次性申请
length长度的连续数组内存,本质是在操作数组而非链表;list->link +=1的操作完全不符合链表指针规则——link是存储下一个节点内存地址的指针,不是偏移计数器,直接做加法运算会指向随机非法内存,根本无法关联节点。 - 返回值设计错误:原函数返回第一个节点的结构体副本,而非链表头指针,后续操作完全无法访问到其他节点,还会造成已申请内存的泄漏。
- 遍历逻辑错误:
main函数中直接对节点副本的link指针做自增操作,既访问不到后续节点数据,还会破坏指针指向。
正确实现逻辑
链表的核心规则:每个节点独立申请内存,头指针指向第一个节点,每个节点的link指针存储下一个节点的内存地址,最后一个节点的link置为NULL作为遍历终点。构建链表的函数必须返回头节点指针,才能让调用方拿到完整的链表。
遍历链表时不要直接修改头指针,要定义临时指针从头部开始,沿着link指针逐个向后移动,直到临时指针为NULL时停止,这是链表遍历的通用范式。
修正后的可运行代码
#include <stdio.h> #include <stdlib.h> typedef struct linked_list { int data; struct linked_list* link; } node; // 构建链表,返回头节点指针 node* linked_list_builder(int length) { if (length <= 0) return NULL; node* head = NULL; // 链表头指针 node* temp = NULL; // 串联节点用的临时指针 node* new_node = NULL; for(int i = 0; i < length; i++) { // 为每个新节点单独申请内存 new_node = (node*)malloc(sizeof(node)); if (new_node == NULL) { printf("内存申请失败\n"); exit(1); } printf("Data in list no.%d at index %d = ", i+1, i); scanf("%d", &new_node->data); new_node->link = NULL; // 新节点暂时作为尾节点,指针置空 if (head == NULL) { // 第一个节点直接作为头节点 head = new_node; temp = head; } else { // 后续节点接在上一个节点的尾部 temp->link = new_node; temp = temp->link; // 临时指针移动到新的尾节点 } } return head; } int main() { int length; printf("Enter the length of Linked list:\n"); scanf("%d", &length); node* list_head = linked_list_builder(length); node* current = list_head; // 遍历专用指针,不直接修改头指针避免丢失链表起点 // 遍历打印链表 int index = 0; while (current != NULL) { printf("index %d->list %d = %d\n", index, index+1, current->data); current = current->link; // 移动到下一个节点 index++; } // 释放所有节点内存,避免内存泄漏 current = list_head; while (current != NULL) { node* to_free = current; current = current->link; free(to_free); } return 0; }
内容的提问来源于stack exchange,提问作者Soham Jobanputra
相关产品推荐
相关产品推荐

