鱼C论坛

 找回密码
 立即注册
查看: 1452|回复: 2

关于链表删除节点的问题

[复制链接]
发表于 2023-9-7 15:51:28 | 显示全部楼层 |阅读模式

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

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

x
本帖最后由 16beat 于 2023-9-7 15:51 编辑
  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <stdlib.h>
  4. void Insert(int data);  //插入
  5. void Delete(int position);  //删除
  6. void print(); //遍历链表
  7. struct Node
  8. {
  9.         int Data;
  10.         struct Node* NextNode;
  11. };
  12. struct Node* HeadNodePointer;
  13. void main()
  14. {
  15.         int n;
  16.         HeadNodePointer = NULL;
  17.         Insert(1);
  18.         Insert(2);
  19.         Insert(3);
  20.         Insert(4);
  21.         Insert(5);
  22.         print();
  23.         Delete(2);
  24.         print();
  25. }
  26. void Insert(int data)
  27. {
  28.         struct Node* temp = (struct Node*)malloc(sizeof(struct Node*));
  29.         (*temp).Data = data;
  30.         (*temp).NextNode = HeadNodePointer;
  31.         HeadNodePointer = temp;
  32. }
  33. void Delete(int position)
  34. {
  35.         struct Node* last = HeadNodePointer;
  36.         if (position == 1)
  37.         {
  38.                 HeadNodePointer = (*last).NextNode;
  39.                 free(last);
  40.                 return;
  41.         }
  42.         for (int n = 0;n < (position - 2);n++)
  43.         {
  44.                 last = (*last).NextNode;
  45.         }
  46.         struct Node* Current = (*last).NextNode;
  47.         (*last).NextNode = (*Current).NextNode;
  48.         free(Current);
  49. }
  50. void print()
  51. {
  52.         struct Node* temp = HeadNodePointer;
  53.         while (temp != NULL)
  54.         {
  55.                 printf("%d ",(*temp).Data);
  56.                 temp = (*temp).NextNode;
  57.         }
  58. }
复制代码


执行到Delete这个函数时会报错,显示
检测到堆损坏:CRT检测到应用程序在堆缓冲区结束后写入内存。
不明白为什么会出现这个问题。
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2023-9-7 15:51:42 | 显示全部楼层
问题的原因是在删除节点时,没有正确地释放内存。在Delete函数中,我们首先找到要删除的节点的前一个节点last,然后将last的NextNode指向要删除节点的NextNode,最后释放要删除的节点Current。然而,在这个代码中,我们没有在释放Current之后将其NextNode设置为NULL,导致last的NextNode指向了一个已经被释放的内存地址。

为了解决这个问题,我们需要在释放Current之后将其NextNode设置为NULL。修改Delete函数的代码如下:

  1. void Delete(int position)
  2. {
  3.     struct Node* last = HeadNodePointer;
  4.     if (position == 1)
  5.     {
  6.         HeadNodePointer = (*last).NextNode;
  7.         free(last);
  8.         return;
  9.     }
  10.     for (int n = 0; n < (position - 2); n++)
  11.     {
  12.         last = (*last).NextNode;
  13.     }
  14.     struct Node* Current = (*last).NextNode;
  15.     (*last).NextNode = (*Current).NextNode;
  16.     free(Current);
  17.     (*last).NextNode = NULL; // 将删除节点后的节点指针设置为NULL
  18. }
复制代码


这样修改后,再次执行程序就不会出现堆损坏的错误了。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-9-7 16:47:48 | 显示全部楼层
isdkz 发表于 2023-9-7 15:51
问题的原因是在删除节点时,没有正确地释放内存。在Delete函数中,我们首先找到要删除的节点的前一个节点la ...

假设当前节点(要删除的节点)为第3个节点,上一个节点为第2个节点,下一个为第4个节点。2号节点的节点指针指向了3号节点(要删除的节点),3号的节点指针则指向了4号,现在我要删除3号节点,需要将2号与4号连接起来,我现在将2号节点的节点指针 由原先指向3号节点改为指向4号节点,然后释放3号,此时2号指向的是4号节点的地址,若加(*last).NextNode = NULL,也就是将2号节点的节点指针置为NULL,那么2号与4号的链接不就断开了吗?本人水平有限,不能够很好得理解,不知道我这么说有无错漏的地方。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-4-22 04:51

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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