鱼C论坛

 找回密码
 立即注册
查看: 542|回复: 5

PTA 7-2 小明打字 链表使用求助

[复制链接]
发表于 2023-9-24 19:19:24 | 显示全部楼层 |阅读模式
40鱼币
微信截图_20230924191700.png
想用双向链表写,但是一直报段错误,不知道原因,求大神救救

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

  4. typedef struct Node{
  5.     char data;
  6.     struct Node * rLink, * lLink; // 设置前驱结点和后继结点
  7. }DblNode, *DblList;

  8. int main(void){
  9.     DblList first;
  10.     first = (DblList) malloc (sizeof(DblNode));
  11.     first -> rLink = first;
  12.     first -> lLink = first;
  13.     DblList s, q, tmp = first;
  14.    
  15.     int insert_flag = 1;
  16.     char ch;

  17.     while((ch = getchar()) != '\n'){
  18.         tmp = (DblList)malloc (sizeof(DblNode));
  19.         if(ch == '['){
  20.             tmp = first -> rLink ;
  21.         }else if(ch == ']'){
  22.             tmp = first -> lLink;
  23.         } else if (ch == '{') {
  24.             if (tmp -> lLink)
  25.                 tmp = tmp -> lLink;
  26.         } else if (ch == '}') {
  27.             if (tmp -> rLink)
  28.                 tmp = tmp -> rLink;
  29.         } else if (ch == '-') {
  30.             insert_flag = insert_flag * (-1);
  31.         }else if(ch == '='){
  32.             DblList t = tmp;
  33.             tmp -> rLink -> lLink = tmp -> lLink;
  34.             tmp -> lLink -> rLink = tmp -> rLink;
  35.             tmp = tmp -> lLink;
  36.             free(t);
  37.         }else{
  38.             s = (DblList) malloc(sizeof(DblNode));
  39.             s -> data = ch;
  40.             q = tmp -> rLink;
  41.             if(insert_flag < 0){
  42.                 s -> lLink = tmp -> lLink;
  43.                 q -> lLink = s;
  44.                 tmp -> lLink -> rLink = s;
  45.                 s -> rLink = q;
  46.             }else{
  47.                 s -> lLink = tmp;
  48.                 q -> lLink = s;
  49.                 tmp -> rLink = s;
  50.                 s -> rLink = q;
  51.             }
  52.             tmp = s;
  53.         }
  54.     }

  55.     // 输出
  56.     DblList p;
  57.     p = first -> rLink;
  58.     while(p != first){
  59.         printf("%c", p -> data);
  60.         p = p -> rLink;
  61.     }
  62. }
复制代码


想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2023-9-24 19:19:37 | 显示全部楼层
段错误通常是由访问非法内存引起的。在你的代码中,可能出现段错误的原因有几个:

1. 在程序一开始,你分配了一个空间用于创建链表的头结点first,但是没有给头结点first赋初值,导致后续操作时可能出现未定义的行为。

解决方法:在分配内存后,初始化头结点的数据和指针为空。
  1. first = (DblList) malloc(sizeof(DblNode));
  2. first->data = '\0';
  3. first->rLink = NULL;
  4. first->lLink = NULL;
复制代码

2. 在插入节点时,你使用了tmp指针,但是没有确保tmp指针不为空。

解决方法:在每次使用tmp指针之前,进行判空处理。
  1. if (tmp != NULL) {
  2.     // 执行操作
  3. }
复制代码

3. 在插入节点时,你没有检查插入位置的前驱节点和后继节点是否为空。

解决方法:在插入节点之前,检查前驱节点和后继节点是否为空。
  1. if (q != NULL && tmp != NULL) {
  2.     // 执行插入操作
  3. }
复制代码

请根据以上建议修改你的代码,并在需要时添加其他必要的错误处理。希望能帮助到你解决问题!如果还有其他疑问,请随时提问。

球一个最佳答案谢谢啦!这对我非常重要!
回答可能有误,多多谅解!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2023-9-24 19:19:41 | 显示全部楼层
你的代码在插入节点时有一些问题,在某些情况下可能会导致段错误(Segmentation Fault)。

具体来说,在以下两种情况下,你分别将 tmp 指针指向了一个已经释放的内存地址:

1. 当输入字符为 [ 时,你将 tmp 指向了双向链表中第一个节点,这个节点是在初始化时分配的内存,而不是通过动态分配获得的,因此在后续的操作中不应该被释放。

2. 当输入字符为 = 时,你删除了当前节点,但是在释放当前节点之前,你先将 tmp 指向了它。在释放节点之后访问同一块内存是未定义行为,有可能导致程序崩溃。

下面是修改后的代码,修复了上述问题。同时,还添加了一些注释来帮助理解:

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

  4. typedef struct Node{
  5.     char data;
  6.     struct Node * rLink, * lLink;
  7. } DblNode, *DblList;

  8. int main(void) {
  9.     // 初始化双向链表
  10.     DblList first;
  11.     first = (DblList) malloc (sizeof(DblNode));
  12.     first -> rLink = first;
  13.     first -> lLink = first;

  14.     // 光标初始位置为双向链表末尾
  15.     DblList tmp = first -> lLink;
  16.     int insert_flag = 1; // 插入标志

  17.     char ch;
  18.     while((ch = getchar()) != '\n') {
  19.         DblList s, q;
  20.         if (ch == '[') { // 将光标移动到双向链表头
  21.             tmp = first -> rLink;
  22.         } else if (ch == ']') { // 将光标移动到双向链表末尾
  23.             tmp = first -> lLink;
  24.         } else if (ch == '{') { // 将光标向左移动一位
  25.             if (tmp -> lLink)
  26.                 tmp = tmp -> lLink;
  27.         } else if (ch == '}') { // 将光标向右移动一位
  28.             if (tmp -> rLink)
  29.                 tmp = tmp -> rLink;
  30.         } else if (ch == '-') { // 切换插入模式
  31.             insert_flag = -insert_flag;
  32.         } else if (ch == '=') { // 删除当前节点
  33.             if (tmp != first && tmp != first -> lLink) {
  34.                 DblList t = tmp;
  35.                 tmp -> rLink -> lLink = tmp -> lLink;
  36.                 tmp -> lLink -> rLink = tmp -> rLink;
  37.                 tmp = tmp -> lLink;
  38.                 free(t);
  39.             }
  40.         } else { // 插入新节点
  41.             s = (DblList) malloc(sizeof(DblNode));
  42.             s -> data = ch;
  43.             q = tmp -> rLink;
  44.             if (insert_flag < 0) {
  45.                 s -> lLink = tmp -> lLink;
  46.                 q -> lLink = s;
  47.                 tmp -> lLink -> rLink = s;
  48.                 s -> rLink = q;
  49.             } else {
  50.                 s -> lLink = tmp;
  51.                 q -> lLink = s;
  52.                 tmp -> rLink = s;
  53.                 s -> rLink = q;
  54.             }
  55.             tmp = s;
  56.         }
  57.     }

  58.     // 输出双向链表
  59.     DblList p = first -> rLink;
  60.     while(p != first) {
  61.         printf("%c", p -> data);
  62.         p = p -> rLink;
  63.     }
  64.     return 0;
  65. }
复制代码


希望这可以帮到你!
如果问题已经解决,请设置最佳答案
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2023-9-24 19:19:43 | 显示全部楼层
这个代码中有几个问题导致了段错误:

1. 在输入字符时,每次都使用malloc动态分配内存,但是并没有及时释放,导致内存泄漏。

2. 在输入字符时,对于特定字符(如'['、']'、'{'、'}'、'-'等),直接将指针指向了特定位置,但是并没有判断这些位置是否存在,导致了访问了非法内存。

3. 在删除节点时,没有判断被删除的节点是否为第一个节点,如果是第一个节点,需要将first指向第二个节点。

下面是修改后的代码:

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

  4. typedef struct Node{
  5.     char data;
  6.     struct Node * rLink, * lLink; // 设置前驱结点和后继结点
  7. }DblNode, *DblList;

  8. int main(void){
  9.     DblList first;
  10.     first = (DblList) malloc (sizeof(DblNode));
  11.     first -> rLink = first;
  12.     first -> lLink = first;
  13.     DblList s, q, tmp = first;

  14.     int insert_flag = 1;
  15.     char ch;

  16.     while((ch = getchar()) != '\n'){
  17.         if(ch == '['){
  18.             tmp = first -> rLink ;
  19.         }else if(ch == ']'){
  20.             tmp = first -> lLink;
  21.         } else if (ch == '{') {
  22.             if (tmp -> lLink)
  23.                 tmp = tmp -> lLink;
  24.         } else if (ch == '}') {
  25.             if (tmp -> rLink)
  26.                 tmp = tmp -> rLink;
  27.         } else if (ch == '-') {
  28.             insert_flag = insert_flag * (-1);
  29.         }else if(ch == '='){
  30.             if (tmp != first) {
  31.                 DblList t = tmp;
  32.                 tmp -> rLink -> lLink = tmp -> lLink;
  33.                 tmp -> lLink -> rLink = tmp -> rLink;
  34.                 tmp = tmp -> lLink;
  35.                 free(t);
  36.             }
  37.         }else{
  38.             s = (DblList) malloc(sizeof(DblNode));
  39.             s -> data = ch;
  40.             q = tmp -> rLink;
  41.             if(insert_flag < 0){
  42.                 s -> lLink = tmp -> lLink;
  43.                 q -> lLink = s;
  44.                 tmp -> lLink -> rLink = s;
  45.                 s -> rLink = q;
  46.             }else{
  47.                 s -> lLink = tmp;
  48.                 q -> lLink = s;
  49.                 tmp -> rLink = s;
  50.                 s -> rLink = q;
  51.             }
  52.             tmp = s;
  53.         }
  54.     }

  55.     // 输出
  56.     DblList p;
  57.     p = first -> rLink;
  58.     while(p != first){
  59.         printf("%c", p -> data);
  60.         p = p -> rLink;
  61.     }

  62.     // 释放内存
  63.     p = first -> rLink;
  64.     while(p != first){
  65.         DblList t = p;
  66.         p = p -> rLink;
  67.         free(t);
  68.     }
  69.     free(first);

  70.     return 0;
  71. }
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2023-9-24 19:23:26 | 显示全部楼层
陶远航 发表于 2023-9-24 19:19
你的代码在插入节点时有一些问题,在某些情况下可能会导致段错误(Segmentation Fault)。

具体来说,在 ...

微信截图_20230924192233.png 大神好像还是不行....结果好像对不上
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2023-9-24 19:24:36 | 显示全部楼层
isdkz 发表于 2023-9-24 19:19
这个代码中有几个问题导致了段错误:

1. 在输入字符时,每次都使用malloc动态分配内存,但是并没有及时 ...

微信截图_20230924192233.png
谢谢大神,但好像还是答案错误
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-4-28 17:38

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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