求大神帮忙看看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:32 编辑
链表初始化并不是一个NULL,而是一个空链表,还有你创建的节点空间都被覆盖掉了
问题太多了,实在是改不过来!!!!!
问题帮你注释了,真的是没法改。帮你修改的时间就可以重新写一个了
//将两个链表连接起来
#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; 链表不是很熟练,帮人就是帮己,让自己练习下,写错也请指正,感谢!
#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;
} 给你写了一个,看看是不是你想要的。
//合并两个链表
#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;
}
_谪仙 发表于 2020-3-3 23:27
链表初始化并不是一个NULL,而是一个空链表,还有你创建的节点空间都被覆盖掉了
感谢!!可以大概讲一下是哪个地方覆盖掉的吗? major_lyu 发表于 2020-3-4 00:46
给你写了一个,看看是不是你想要的。
好的,谢谢你!!{:5_108:} 4goodworld 发表于 2020-3-3 23:55
链表不是很熟练,帮人就是帮己,让自己练习下,写错也请指正,感谢!
谢谢你,我也好好学习一下!
页:
[1]