鱼C论坛

 找回密码
 立即注册
查看: 1676|回复: 10

[已解决]关于链表多次插入的问题

[复制链接]
发表于 2021-1-22 15:06:05 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
这个程序是创建一个保存学生编号和成绩的链表,然后实现在链表里插入一个学生的信息和成绩。单次插入学生信息的函数我写完了,就是那个add()函数,现在我想用这个函数来实现多次插入信息。我截的这一段程序是输入要插入的学生信息然后调用add函数,完整程序在后面。我的思路是,当addstu这个节点完成插入后,将它释放然后重新赋值,再次插入,但是写的这段代码有问题,问题在哪呢,又该怎么实现多次插入节点?求大佬解答。
  1. while(1)
  2.         {
  3.                 addstu=(struct student *)malloc(sizeof(struct student));
  4.                 addstu->num=0;
  5.                 addstu->score=0;
  6.                 addstu->next=NULL;
  7.                 printf("请输入你想加入的学生的编号和成绩(输入0结束添加):");
  8.                 scanf("%d,%f",&addstu->num,&addstu->score);
  9.                 printf("\n");
  10.                 add(stu,addstu);
  11.                 free(addstu);
  12.                 if(0==addstu->num)
  13.                 {
  14.                         break;
  15.                 }
  16.         }
复制代码



完整程序:

  1. #include <stdio.h>
  2. #include <malloc.h>


  3. struct student
  4. {
  5.         int num;
  6.         float score;
  7.         struct student *next;
  8. };
  9. int n;
  10. int main(void)
  11. {
  12.         struct student *creat();
  13.         void print(struct student *r);
  14.         void del(struct student *q,int num1);
  15.         void add(struct student *a,struct student *a0);

  16.         int m;
  17.         struct student *stu;
  18.         struct student *addstu;

  19.         stu=creat();
  20.         printf("\nThere are %d record!\n\n",n);
  21.         print(stu);

  22.         printf("请输入你想删除的学生的编号:");
  23.         scanf("%d",&m);
  24.         while(m==0)
  25.         {
  26.                 printf("不能为0请重新输入:");
  27.                 scanf("%d",&m);
  28.         }
  29.         printf("\n");
  30.         del(stu,m);

  31.         while(1)
  32.         {
  33.                 addstu=(struct student *)malloc(sizeof(struct student));
  34.                 addstu->num=0;
  35.                 addstu->score=0;
  36.                 addstu->next=NULL;
  37.                 printf("请输入你想加入的学生的编号和成绩(输入0结束添加):");
  38.                 scanf("%d,%f",&addstu->num,&addstu->score);
  39.                 printf("\n");
  40.                 add(stu,addstu);
  41.                 free(addstu);
  42.                 if(0==addstu->num)
  43.                 {
  44.                         break;
  45.                 }
  46.         }

  47.         printf("\n\n");
  48. }
  49. struct student *creat()
  50. {
  51.         struct student *p1,*p2,*head;
  52.         n=0;
  53.         head=NULL;
  54.         p2=(struct student *)malloc(sizeof(struct student));
  55.         while(1)
  56.         {
  57.                 p1=(struct student *)malloc(sizeof(struct student));
  58.                 printf("Please enter this student number:");
  59.                 scanf("%d",&p1->num);
  60.                 printf("Please enter this student score:");
  61.                 scanf("%f",&p1->score);
  62.                 if(0==p1->num)
  63.                 {
  64.                         break;
  65.                 }
  66.                 else
  67.                 {
  68.                         n++;
  69.                         if(1==n)
  70.                         {
  71.                                 head=p1;
  72.                                 p2=p1;
  73.                         }
  74.                         else
  75.                         {
  76.                                 p2->next=p1;
  77.                                 p2=p1;
  78.                         }
  79.                 }               
  80. }
  81.         p2->next=NULL;

  82.         return head;
  83. }
  84. void print(struct student *r)
  85. {
  86.        
  87.         while(r)
  88.         {
  89.                 printf("第 %d 位学生的成绩是 %.2f\n",r->num,r->score);
  90.                 r=r->next;
  91.         }
  92.         printf("\n");
  93. }
  94. void del(struct student *q,int num1)
  95. {
  96.         void print(struct student *r);

  97.         struct student *q1,*q2,*q3;
  98.         q1=q3=q;

  99.         if(q==NULL)
  100.         {
  101.                 printf("空表不能操作!");
  102.         }
  103.         else
  104.         {
  105.                 while(1)
  106.                 {
  107.                         int i=0;
  108.                         while(1)
  109.                         {
  110.                                 if(num1==q3->num)
  111.                                 {
  112.                                         i=1;
  113.                                         break;
  114.                                 }
  115.                                 if(q3->next==NULL)
  116.                                 {
  117.                                         break;
  118.                                 }
  119.                                 q3=q3->next;
  120.                         }
  121.                         if(0==i)
  122.                         {
  123.                                 printf("没有该学生信息!\n请重新输入:");
  124.                                 scanf("%d",&num1);
  125.                                 q3=q;
  126.                         }
  127.                         if(1==i)
  128.                                 break;
  129.                 }
  130.                 printf("\n");
  131.                 if(num1==q1->num)
  132.                 {
  133.                         q=q->next;
  134.                 }
  135.                 else
  136.                 {
  137.                         while(1)
  138.                         {
  139.                                 if(num1!=q1->num)
  140.                                 {
  141.                                         q2=q1;
  142.                                         q1=q1->next;
  143.                                 }
  144.                                 else
  145.                                 {
  146.                                         q2->next=q1->next;
  147.                                         free(q1);
  148.                                         break;
  149.                                 }
  150.                         }
  151.                 }
  152.                 printf("\nThere are %d record!\n\n",n-1);
  153.                 print(q);
  154.                 printf("%d号学生成绩已删除\n\n",num1);
  155.         }

  156. }
  157. void add(struct student *a,struct student *a0)
  158. {
  159.         struct student *a1,*a2,*a3;
  160.         a1=a;

  161.         if(a0->num<a->num)//第一种情况,插入节点编号在首节点前
  162.         {
  163.                 a0->next=a;
  164.                 a=a0;
  165.         }
  166.         else
  167.         {
  168.                 while(1)
  169.                 {
  170.                         if(a1->next==NULL)
  171.                         {
  172.                                 a3=a1;
  173.                                 break;
  174.                         }
  175.                         a1=a1->next;
  176.                 }

  177.                 a1=a;
  178.                 if(a0->num>a3->num)
  179.                 {
  180.                         a3->next=a0;
  181.                         a0->next=NULL;
  182.                 }
  183.                 else
  184.                 {
  185.                         while(1)
  186.                         {
  187.                                 if(a0->num<a1->num)
  188.                                 {
  189.                                         a2->next=a0;
  190.                                         a0->next=a1;
  191.                                         break;
  192.                                 }
  193.                                 a2=a1;
  194.                                 a1=a1->next;

  195.                         }
  196.                 }
  197.         }
  198.         printf("\nThere are %d record!\n\n",n);
  199.         print(a);//函数嵌套使用
  200.         printf("%d号学生成绩添加成功\n\n",a0->num);
  201. }
复制代码
最佳答案
2021-1-22 15:57:42
代码太长,没细看。至少有两个主要问题。

1、被链接到链表的节点为什么要 free ? 内存分配后,只要还要使用,就不能 free,free后就不能再去访问。

2、add()这个函数里没有判断表头是否为空,都表头为空时,访问出错。

还有就是 malloc 分配的内存在程序结束前没有 free。
create 函数里,输入学号0 的时候,不生成表头,但是分配的内存又没有释放。

评分

参与人数 1荣誉 +1 鱼币 +1 贡献 +3 收起 理由
旋风0级 + 1 + 1 + 3

查看全部评分

小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2021-1-22 16:13:27 | 显示全部楼层
xieglt 发表于 2021-1-22 15:57
代码太长,没细看。至少有两个主要问题。

1、被链接到链表的节点为什么要 free ? 内存分配后,只要还要 ...

哦,去掉free就可以多次了,free函数没仔细去研究,我以为free完后只要重新分配内存就可以用。
add没判断是因为我懒得去写了,然后前面直接声明不让输入0,但是后来前面的声明又改了
还有我想问一下,你说free后不能用了只是当前函数不能用了吗?
还有你说程序结束前free,是在主程序的末尾free吗?如果不free会怎么样?
求大哥解答!
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-1-22 16:45:13 | 显示全部楼层
xieglt 发表于 2021-1-22 16:32
分配的内存不释放会造成内存泄露。
如果你的程序一直在分配内存而不释放,会造成系统可用内存越来越少, ...

我刚刚试了在子函数释放内存很容易出错,但是我有个疑问,形参在使用完成后不是系统会自动释放内存吗,意思子函数内部是不是不必使用free函数,只需要在main函数执行free操作就行了?
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-1-22 17:00:18 | 显示全部楼层
xieglt 发表于 2021-1-22 16:53
好难解释。
子函数内部分配的内存,如果能把内存指针传出来,在main里面free就可以。
比如说链表节点, ...

哈哈哈好吧,我再研究一下,谢谢你
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-1-25 11:03:43 | 显示全部楼层
xieglt 发表于 2021-1-22 16:53
好难解释。
子函数内部分配的内存,如果能把内存指针传出来,在main里面free就可以。
比如说链表节点, ...

哥我再请教一下关于free函数的问题,是不是可以这样理解,只有直接使用malloc函数分配内存的变量才需要去free,而在其他函数调用这些变量的形参是不用去free的,除非在函数内又使用了malloc。比如我在main函数用malloc给p1分配了内存,然后在子函数的形参q1调用了p1,那q1是不用free的?
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-1-25 13:19:27 | 显示全部楼层
xieglt 发表于 2021-1-25 11:49
操作系统对内存管理通常是这样的。
用户程序提出内存分配申请 ----> 操作系统在内存中寻找一块符合用户 ...

好的,明白了,非常感谢!
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-9-23 07:59

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表