鱼C论坛

 找回密码
 立即注册
查看: 1198|回复: 7

[已解决]求大神帮忙看看segmentation问题出在哪里

[复制链接]
发表于 2020-3-3 22:52:59 | 显示全部楼层 |阅读模式

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

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

x
本帖最后由 Shaky_00 于 2020-3-3 23:16 编辑

一个关于将两个链表连接起来的问题,数据结构入门级程序,在DevCpp上运行出来显示segmentation fault,帮忙看看该怎么修改一下,谢谢!!!

源代码如下:

//将两个链表连接起来
#include<stdio.h>
#include<malloc.h>
#define LEN sizeof(List)

typedef struct node{
        int data;
        struct node * next;
}List;

int main()
{
        // 首先得到m和n的值
        int m, n;
        int count1, count2;
        printf("请输入两个链表的长度m与n:");
        scanf("%d %d", &m, &n);
        List * L1;
        List * L2;//两串需要串联的列表
        L1 = NULL;
        L2 = NULL;//指针初始化
        List *ha, *hb, *hc;//分别指向三个的head
        ha = (List*)malloc(LEN);
        hb = (List*)malloc(LEN);
        hc = (List*)malloc(LEN);//给指针分配内存

        ha = L1;
        hb = L2;
        hc = L1;//指针的初始化

        while(count1 < m)//当读数小于m值时,继续读数进L1表
        {
                scanf("%d", &ha->data);
                ha = ha->next;
                count1++;
        }
        hb = ha;
        free(ha);
        while(count2 < n)
        {
                scanf("%d", &hb->data);
                hb = hb->next;
                count2++;
        }
        hb = NULL;

        while(L1 != NULL)
        {
                do{
                        printf("%d->", hc->data);
                        hc = hc->next;
                }while(hc != NULL);
        }

        return 0;
}
最佳答案
2020-3-3 23:30:59
问题太多了,实在是改不过来!!!!!

问题帮你注释了,真的是没法改。帮你修改的时间就可以重新写一个了
  1. //将两个链表连接起来
  2. #include <stdio.h>
  3. #include <malloc.h>

  4. #define LEN sizeof(List) //这个定义是一个List node 的大小,并不是List长度

  5. typedef struct node
  6. {
  7.     int data;
  8.     struct node *next;
  9. } List;

  10. int main()
  11. {
  12.     // 首先得到m和n的值
  13.     int m, n;
  14.     int count1, count2;
  15.     printf("请输入两个链表的长度m与n:");
  16.     scanf("%d %d", &m, &n);
  17.     List *L1;
  18.     List *L2;
  19.     L1 = NULL;
  20.     L2 = NULL;
  21.     List *ha, *hb, *hc;
  22.     //ha = (List*)malloc(LEN); //这样分配的空间只能存储一个List node. 下同
  23.     //hb = (List*)malloc(LEN);
  24.     //hc = (List*)malloc(LEN);

  25.     ha = (List *)malloc(m * LEN); //这样分配的才是m个结点的List,下同
  26.     hb = (List *)malloc(n * LEN);
  27.     hc = (List *)malloc((m + n) * LEN);

  28.     //ha = L1; //这三步执行完 ha = NULL, ha = NULL, hc = NULL,
  29.     //所以后面对ha,hb,hc的操作都是对NULL指针所指空间的操作,当然segmentation fault
  30.     //hb = L2;
  31.     //hc = L1;
  32.     L1 = ha;
  33.     L2 = hb;
  34.     hc = L1; // hc现在和L1指向同一个空间,上面为hc分配的空间就此放弃,永远也访问不到了!!!!!!

  35.     count1 = 0;
  36.     while (count1 < m) // count1没有赋初值,虽然大多数情况下默认值是0,但这样很不安全
  37.     {
  38.         scanf("%d", &ha->data);
  39.         ha = ha->next;  //上面只是分配了存储List的空间,但是并没有建立处理链表结构,这是,ha->next的值并真的就是用空间。你这样做ha第二个往后的结点就访问不到了d//
  40.         count1++;
  41.     }
  42.     hb = ha; //hb和ha指向同一空间,
  43.     free(ha); // free(ha),相当于把hb,和 ha指向的那个结点空间释放了,那么hb,和ha指针都悬空了。你这样做ha第二个往后的结点就访问不到了
  44.               //执行完这一步, hb指向的空间已经被free了, 那么下面对hb的访问也就segmentation fault了
  45.               // 就算上面的都没问题了,当跳出上面的while时,ha指向的是L1的最后一个结点之后的结点, 下面的while访问hb时访问的就是个没有分配的空间
  46. //
  47.     while (count2 < n)
  48.     {
  49.         scanf("%d", &hb->data);
  50.         hb = hb->next;
  51.         count2++;
  52.     }
  53.     hb = NULL; //这种赋值没有必要的,并不能节省空间
  54.     // 到目前为止,没看到链表拼接的任何操作
  55.     while (L1 != NULL) //这个循环永远不会结束。L1的值在整个循环中不会改变,也永远不可能等于NULL
  56.     {
  57.         do
  58.         {
  59.             printf("%d->",hc->data);
  60.             hc = hc->next;
  61.         } while (hc != NULL);
  62.         // 这个内层循环跳出后会在外层while中一直空转。你这内层循环和外层循环有什么关系吗。
  63.     }

  64.     return 0;
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2020-3-3 23:27:42 | 显示全部楼层
本帖最后由 _谪仙 于 2020-3-3 23:32 编辑

链表初始化并不是一个NULL,而是一个空链表,还有你创建的节点空间都被覆盖掉了
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-3-3 23:30:59 | 显示全部楼层    本楼为最佳答案   
问题太多了,实在是改不过来!!!!!

问题帮你注释了,真的是没法改。帮你修改的时间就可以重新写一个了
  1. //将两个链表连接起来
  2. #include <stdio.h>
  3. #include <malloc.h>

  4. #define LEN sizeof(List) //这个定义是一个List node 的大小,并不是List长度

  5. typedef struct node
  6. {
  7.     int data;
  8.     struct node *next;
  9. } List;

  10. int main()
  11. {
  12.     // 首先得到m和n的值
  13.     int m, n;
  14.     int count1, count2;
  15.     printf("请输入两个链表的长度m与n:");
  16.     scanf("%d %d", &m, &n);
  17.     List *L1;
  18.     List *L2;
  19.     L1 = NULL;
  20.     L2 = NULL;
  21.     List *ha, *hb, *hc;
  22.     //ha = (List*)malloc(LEN); //这样分配的空间只能存储一个List node. 下同
  23.     //hb = (List*)malloc(LEN);
  24.     //hc = (List*)malloc(LEN);

  25.     ha = (List *)malloc(m * LEN); //这样分配的才是m个结点的List,下同
  26.     hb = (List *)malloc(n * LEN);
  27.     hc = (List *)malloc((m + n) * LEN);

  28.     //ha = L1; //这三步执行完 ha = NULL, ha = NULL, hc = NULL,
  29.     //所以后面对ha,hb,hc的操作都是对NULL指针所指空间的操作,当然segmentation fault
  30.     //hb = L2;
  31.     //hc = L1;
  32.     L1 = ha;
  33.     L2 = hb;
  34.     hc = L1; // hc现在和L1指向同一个空间,上面为hc分配的空间就此放弃,永远也访问不到了!!!!!!

  35.     count1 = 0;
  36.     while (count1 < m) // count1没有赋初值,虽然大多数情况下默认值是0,但这样很不安全
  37.     {
  38.         scanf("%d", &ha->data);
  39.         ha = ha->next;  //上面只是分配了存储List的空间,但是并没有建立处理链表结构,这是,ha->next的值并真的就是用空间。你这样做ha第二个往后的结点就访问不到了d//
  40.         count1++;
  41.     }
  42.     hb = ha; //hb和ha指向同一空间,
  43.     free(ha); // free(ha),相当于把hb,和 ha指向的那个结点空间释放了,那么hb,和ha指针都悬空了。你这样做ha第二个往后的结点就访问不到了
  44.               //执行完这一步, hb指向的空间已经被free了, 那么下面对hb的访问也就segmentation fault了
  45.               // 就算上面的都没问题了,当跳出上面的while时,ha指向的是L1的最后一个结点之后的结点, 下面的while访问hb时访问的就是个没有分配的空间
  46. //
  47.     while (count2 < n)
  48.     {
  49.         scanf("%d", &hb->data);
  50.         hb = hb->next;
  51.         count2++;
  52.     }
  53.     hb = NULL; //这种赋值没有必要的,并不能节省空间
  54.     // 到目前为止,没看到链表拼接的任何操作
  55.     while (L1 != NULL) //这个循环永远不会结束。L1的值在整个循环中不会改变,也永远不可能等于NULL
  56.     {
  57.         do
  58.         {
  59.             printf("%d->",hc->data);
  60.             hc = hc->next;
  61.         } while (hc != NULL);
  62.         // 这个内层循环跳出后会在外层while中一直空转。你这内层循环和外层循环有什么关系吗。
  63.     }

  64.     return 0;
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-3-3 23:55:09 | 显示全部楼层
链表不是很熟练,帮人就是帮己,让自己练习下,写错也请指正,感谢!
  1. #include<stdio.h>
  2. #include<malloc.h>
  3. #define LEN sizeof(List)

  4. typedef struct node {
  5.         int data;
  6.         struct node * next;
  7. }List;

  8. int main()
  9. {
  10.         // 首先得到m和n的值
  11.         int m, n;
  12.         int count1,count2;
  13.         count1 = count2 = 0;

  14.         printf("请输入两个链表的长度m与n:");
  15.         scanf("%d %d", &m, &n);
  16.         List * L1;
  17.         List * L2;//两串需要串联的列表
  18.         L1 = NULL;
  19.         L2 = NULL;//指针初始化
  20.         List *ha, *hb, *Head;


  21.          ha = (List*)malloc(LEN);//给指针分配内存
  22.          Head =hb= NULL;
  23.         while (count1 < m)//当读数小于m值时,继续读数进L1表
  24.         {
  25.                 count1++;
  26.                 printf("请输入链表%d data:\n",count1);
  27.                 scanf("%d", &ha->data);
  28.                 if (count1 == 1)Head = ha;
  29.                 else  hb->next=ha;
  30.                 hb = ha;
  31.                 ha = (List*)malloc(LEN);
  32.         }
  33.         hb ->next = NULL;
  34.         L1 = Head;


  35.         ha = (List*)malloc(LEN);//给指针分配内存
  36.         Head = hb = NULL;
  37.         while (count2 < n)
  38.         {
  39.                 count2++;
  40.                 printf("请输入链表2data:\n");
  41.                 scanf("%d", &ha->data);
  42.                 if (count2 == 1)Head = ha;
  43.                 else  hb->next = ha;
  44.                 hb = ha;
  45.                 ha = (List*)malloc(LEN);
  46.         }
  47.         hb->next = NULL;
  48.         L2= Head;

  49.         Head = L1;
  50.         printf("%d %d\n", L1, L2);
  51.         do{
  52.                 printf("%x", L1->next);
  53.                 if (L1->next == NULL) {
  54.                         L1->next = L2;
  55.                         break;
  56.                 }
  57.                 L1 = L1->next;       
  58.         } while (L1 != NULL);
  59.         L1 = Head;

  60.         while (L1 != NULL)
  61.         {
  62.                 printf("打印合并的效果:\n");
  63.                 do {
  64.                         printf("%d->", L1->data);
  65.                         L1 = L1->next;
  66.                 } while (L1 != NULL);
  67.         }
  68.         /*
  69.         free
  70.        
  71.         */
  72.         return 0;
  73. }
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

发表于 2020-3-4 00:46:41 | 显示全部楼层
给你写了一个,看看是不是你想要的。


  1. //合并两个链表
  2. #include <stdio.h>
  3. #include <malloc.h>

  4. typedef struct node
  5. {
  6.     int data;
  7.     struct node *next;
  8. } List;

  9. //合并连个list L1 和 L2
  10. List *mergeList(List *L1, List *L2)
  11. {
  12.     //两个空链表直接返回空链表
  13.     if (L1 == NULL && L2 == NULL)
  14.         return NULL;
  15.     // 第一个链表为空,直接返回第二链表
  16.     if (L1 == NULL)
  17.         return L2;
  18.     // 第二链表为空,直接返回第一个链表
  19.     if (L2 == NULL)
  20.         return L1;
  21.     //如果两个链表都不为空,进行合并
  22.     List *rslt = (List *)malloc(sizeof(List));
  23.     List *ptr = rslt;
  24.     //复制第一个链表到结果链表
  25.     while (L1 != NULL)
  26.     {
  27.         ptr->data = L1->data;
  28.         ptr->next = (List *)malloc(sizeof(List));
  29.         ptr = ptr->next;
  30.         L1 = L1->next;
  31.     }
  32.     //复制第二个链表的数据建立后续结点
  33.     while (L2->next != NULL)
  34.     {
  35.         ptr->data = L2->data;
  36.         ptr->next = (List *)malloc(sizeof(List));
  37.         ptr = ptr->next;
  38.         L2 = L2->next;
  39.     }
  40.     ptr->data = L2->data;
  41.     ptr->next = NULL;
  42.     return rslt;
  43. }

  44. void printList(List *list) // 打印List
  45. {
  46.     while (list != NULL)
  47.     {
  48.         printf("%d->", list->data);
  49.         list = list->next;
  50.     }
  51.     printf("NULL\n");
  52. }

  53. //从终端读取n个整数构建链表
  54. List *constructList(int n)
  55. {
  56.     if (n == 0)
  57.         return NULL;
  58.     List *list = (List *)malloc(sizeof(List));
  59.     List *ha = list;
  60.     printf("Please input %d integers to construct list:\n", n);
  61.     while (n > 1)
  62.     {
  63.         scanf("%d", &ha->data);
  64.         ha->next = (List *)malloc(sizeof(List));
  65.         ha = ha->next;
  66.         n--;
  67.     }
  68.     scanf("%d", &ha->data);
  69.     ha->next = NULL;
  70.     return list;
  71. }

  72. int main()
  73. {
  74.     int m, n;
  75.     printf("Please input the length of two lists:\n");
  76.     scanf("%d %d", &m, &n);
  77.     List *L1 = constructList(m);
  78.     List *L2 = constructList(n);
  79.     List *L3 = NULL;
  80.     printList(L1);
  81.     printList(L2);
  82.     L3 = mergeList(L1, L2);
  83.     printList(L3);

  84.     return 0;
  85. }
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

 楼主| 发表于 2020-3-4 01:44:38 | 显示全部楼层
_谪仙 发表于 2020-3-3 23:27
链表初始化并不是一个NULL,而是一个空链表,还有你创建的节点空间都被覆盖掉了

感谢!!可以大概讲一下是哪个地方覆盖掉的吗?
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-3-4 01:48:29 | 显示全部楼层
major_lyu 发表于 2020-3-4 00:46
给你写了一个,看看是不是你想要的。

好的,谢谢你!!
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-3-4 01:49:27 | 显示全部楼层
4goodworld 发表于 2020-3-3 23:55
链表不是很熟练,帮人就是帮己,让自己练习下,写错也请指正,感谢!

谢谢你,我也好好学习一下!
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-7-6 12:45

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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