Shaky_00 发表于 2020-3-3 22:52:59

求大神帮忙看看segmentation问题出在哪里

本帖最后由 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:27:42

本帖最后由 _谪仙 于 2020-3-3 23:32 编辑

链表初始化并不是一个NULL,而是一个空链表,还有你创建的节点空间都被覆盖掉了

major_lyu 发表于 2020-3-3 23:30:59

问题太多了,实在是改不过来!!!!!

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

#define LEN sizeof(List) //这个定义是一个List node 的大小,并不是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;
    //ha = (List*)malloc(LEN); //这样分配的空间只能存储一个List node. 下同
    //hb = (List*)malloc(LEN);
    //hc = (List*)malloc(LEN);

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

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

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

    return 0;

4goodworld 发表于 2020-3-3 23:55:09

链表不是很熟练,帮人就是帮己,让自己练习下,写错也请指正,感谢!
#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;
        count1 = count2 = 0;

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


       ha = (List*)malloc(LEN);//给指针分配内存
       Head =hb= NULL;
        while (count1 < m)//当读数小于m值时,继续读数进L1表
        {
                count1++;
                printf("请输入链表%d data:\n",count1);
                scanf("%d", &ha->data);
                if (count1 == 1)Head = ha;
                elsehb->next=ha;
                hb = ha;
                ha = (List*)malloc(LEN);
        }
        hb ->next = NULL;
        L1 = Head;


        ha = (List*)malloc(LEN);//给指针分配内存
        Head = hb = NULL;
        while (count2 < n)
        {
                count2++;
                printf("请输入链表2data:\n");
                scanf("%d", &ha->data);
                if (count2 == 1)Head = ha;
                elsehb->next = ha;
                hb = ha;
                ha = (List*)malloc(LEN);
        }
        hb->next = NULL;
        L2= Head;

        Head = L1;
        printf("%d %d\n", L1, L2);
        do{
                printf("%x", L1->next);
                if (L1->next == NULL) {
                        L1->next = L2;
                        break;
                }
                L1 = L1->next;       
        } while (L1 != NULL);
        L1 = Head;

        while (L1 != NULL)
        {
                printf("打印合并的效果:\n");
                do {
                        printf("%d->", L1->data);
                        L1 = L1->next;
                } while (L1 != NULL);
        }
        /*
        free
       
        */
        return 0;
}

major_lyu 发表于 2020-3-4 00:46:41

给你写了一个,看看是不是你想要的。


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

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

//合并连个list L1 和 L2
List *mergeList(List *L1, List *L2)
{
    //两个空链表直接返回空链表
    if (L1 == NULL && L2 == NULL)
      return NULL;
    // 第一个链表为空,直接返回第二链表
    if (L1 == NULL)
      return L2;
    // 第二链表为空,直接返回第一个链表
    if (L2 == NULL)
      return L1;
    //如果两个链表都不为空,进行合并
    List *rslt = (List *)malloc(sizeof(List));
    List *ptr = rslt;
    //复制第一个链表到结果链表
    while (L1 != NULL)
    {
      ptr->data = L1->data;
      ptr->next = (List *)malloc(sizeof(List));
      ptr = ptr->next;
      L1 = L1->next;
    }
    //复制第二个链表的数据建立后续结点
    while (L2->next != NULL)
    {
      ptr->data = L2->data;
      ptr->next = (List *)malloc(sizeof(List));
      ptr = ptr->next;
      L2 = L2->next;
    }
    ptr->data = L2->data;
    ptr->next = NULL;
    return rslt;
}

void printList(List *list) // 打印List
{
    while (list != NULL)
    {
      printf("%d->", list->data);
      list = list->next;
    }
    printf("NULL\n");
}

//从终端读取n个整数构建链表
List *constructList(int n)
{
    if (n == 0)
      return NULL;
    List *list = (List *)malloc(sizeof(List));
    List *ha = list;
    printf("Please input %d integers to construct list:\n", n);
    while (n > 1)
    {
      scanf("%d", &ha->data);
      ha->next = (List *)malloc(sizeof(List));
      ha = ha->next;
      n--;
    }
    scanf("%d", &ha->data);
    ha->next = NULL;
    return list;
}

int main()
{
    int m, n;
    printf("Please input the length of two lists:\n");
    scanf("%d %d", &m, &n);
    List *L1 = constructList(m);
    List *L2 = constructList(n);
    List *L3 = NULL;
    printList(L1);
    printList(L2);
    L3 = mergeList(L1, L2);
    printList(L3);

    return 0;
}

Shaky_00 发表于 2020-3-4 01:44:38

_谪仙 发表于 2020-3-3 23:27
链表初始化并不是一个NULL,而是一个空链表,还有你创建的节点空间都被覆盖掉了

感谢!!可以大概讲一下是哪个地方覆盖掉的吗?

Shaky_00 发表于 2020-3-4 01:48:29

major_lyu 发表于 2020-3-4 00:46
给你写了一个,看看是不是你想要的。

好的,谢谢你!!{:5_108:}

Shaky_00 发表于 2020-3-4 01:49:27

4goodworld 发表于 2020-3-3 23:55
链表不是很熟练,帮人就是帮己,让自己练习下,写错也请指正,感谢!

谢谢你,我也好好学习一下!
页: [1]
查看完整版本: 求大神帮忙看看segmentation问题出在哪里