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

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;
}

修正说明

  1. 修正malloc的内存大小,改为sizeof(struct Node)确保分配足够的内存。
  2. 将q变量移到循环外部,首次创建节点时初始化q,避免野指针访问。
  3. 添加while(getchar() != '\n')清除输入缓冲区的残留换行符,确保正确读取用户的选择字符。
  4. 优化循环条件为ch == 'y' || ch == 'Y',增强鲁棒性。
  5. 在display函数末尾添加NULL标记,明确链表结束位置。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 01:10:26