C语言单链表打印出现垃圾值,请求排查代码错误
C语言单链表打印出现垃圾值的问题排查与修复
问题描述
尝试用C语言实现单链表的创建与打印功能,打印输入的值后出现垃圾值。使用do-while循环编写create函数创建链表,display函数用于打印链表,以下是尝试的代码及输出结果。
原代码
#include <stdio.h> #include <stdlib.h> //Declaring the struct variable struct Node { int data; struct Node *link; }*head=NULL; //Creating the Linked List void create() { char ch= 'y'; do { printf("ch : %c",ch); struct Node *p,*q; p = (struct Node*)malloc(sizeof(struct Node*)); printf("\nEnter the Data : \n"); scanf("%d", &p->data); p->link = NULL; if(head == NULL) { head = p; } else { q->link = p; } q=p; scanf("%c",&ch); }while(ch!= 'n'); } //Displaying the Linked List void display() { struct Node *p=head; if(p == NULL) { printf("\n List is Empty \n"); } else { while(p!=NULL) { printf("%d -->", p->data); p = p->link; } } } int main() { printf("\n Enter the data into the linked list: \n"); create(); printf("\nCreation Complete........ Displaying\n"); display(); return 0; }
原输出
1 2 3 4 5 6 n Creation Complete........ Displaying 1 --> 2 --> 3 --> 4 --> 5 --> 6 -->7097656 -->
错误分析
- 内存分配大小错误:
malloc(sizeof(struct Node*))分配的是指针类型的内存空间(通常4/8字节),而不是struct Node结构体的完整大小。内存分配不足会导致后续对节点的访问越界,破坏链表结构,最终出现垃圾值。 - 野指针访问:
q是create函数内的局部变量,首次进入else分支时q未初始化,直接执行q->link = p会访问非法内存,导致链表节点的link指针被错误赋值,打印时出现非法地址的垃圾数据。 - 输入缓冲区残留问题:
scanf("%d", &p->data)读取整数后,输入缓冲区会留下换行符,后续scanf("%c",&ch)会直接读取这个换行符,导致循环逻辑异常(比如误判用户输入,创建多余节点或提前终止)。
修正后的代码
#include <stdio.h> #include <stdlib.h> struct Node { int data; struct Node *link; }*head=NULL; void create() { char ch= 'y'; // 将q提升到循环外,避免每次循环重新初始化 struct Node *q = NULL; do { printf("ch : %c\n",ch); struct Node *p; // 分配结构体Node的完整大小 p = (struct Node*)malloc(sizeof(struct Node)); if(p == NULL){ printf("内存分配失败\n"); return; } printf("Enter the Data : \n"); scanf("%d", &p->data); p->link = NULL; if(head == NULL) { head = p; q = p; // 首次初始化q } else { q->link = p; q = p; } // 清除输入缓冲区的残留字符 while(getchar() != '\n'); printf("是否继续输入?(y/n): "); scanf("%c",&ch); }while(ch == 'y' || ch == 'Y'); } void display() { struct Node *p=head; if(p == NULL) { printf("\n List is Empty \n"); return; } printf("\n链表内容:"); while(p!=NULL) { printf("%d -->", p->data); p = p->link; } printf("NULL\n"); // 标记链表结束 } int main() { printf("\nEnter the data into the linked list: \n"); create(); printf("\nCreation Complete........ Displaying\n"); display(); return 0; }
修正说明
- 修正
malloc的内存大小,改为sizeof(struct Node)确保分配足够的内存。 - 将
q变量移到循环外部,首次创建节点时初始化q,避免野指针访问。 - 添加
while(getchar() != '\n')清除输入缓冲区的残留换行符,确保正确读取用户的选择字符。 - 优化循环条件为
ch == 'y' || ch == 'Y',增强鲁棒性。 - 在
display函数末尾添加NULL标记,明确链表结束位置。
内容的提问来源于stack exchange,提问作者SUBARAM RAM
相关产品推荐
相关产品推荐

