C将链表结构传递给函数
我用C实现了一个链表 问题是,每当我尝试使用函数C将链表结构传递给函数,c,struct,linked-list,segmentation-fault,C,Struct,Linked List,Segmentation Fault,我用C实现了一个链表 问题是,每当我尝试使用函数print\u list(struct linked\u list*list)打印节点数据时,我都会遇到分段错误 我不确定是什么原因导致了它,因为当我尝试打印(struct linked_list*list)时,它工作正常 而且,当我尝试动态分配内存时,它也可以正常工作。但我很好奇这样的代码有什么问题?为什么使用print不会导致同样的错误 #include <stdio.h> #include <stdlib.h> st
print\u list(struct linked\u list*list)
打印节点数据时,我都会遇到分段错误
我不确定是什么原因导致了它,因为当我尝试打印(struct linked_list*list)时,它工作正常
而且,当我尝试动态分配内存时,它也可以正常工作。但我很好奇这样的代码有什么问题?为什么使用print
不会导致同样的错误
#include <stdio.h>
#include <stdlib.h>
struct node{
char data;
struct node* next;
};
struct linked_list{
struct node *head;
};
void concat(struct linked_list* list1, struct linked_list* list2)
{
struct node* tmp = list1->head;
while(tmp->next != NULL)
tmp = tmp->next;
tmp->next = list2->head;
}
void print_list(struct linked_list *list)
{
struct node* tmp = list->head;
while(tmp != NULL){
printf("%c - ", tmp->data);
tmp = tmp->next;}
printf("\n");
}
void print(struct linked_list *list)
{
struct node* tmp = list->head;
printf("%c\n", tmp->data);
tmp = tmp->next;
printf("%c\n", tmp->data);
tmp = tmp->next;
printf("%c\n", tmp->data);
}
int main()
{
struct linked_list list1,list2;
struct node n1,n2,n3,n4,n5;
n1.data = 'A';
n2.data = 'B';
n3.data = 'C';
n4.data = 'D';
n5.data = 'E';
n1.next = &n2;
n2.next = &n3;
n4.next = &n5;
list1.head = &n1;
list2.head = &n4;
printf("List 1 containes :\n");
print_list(&list1);
concat(&list1,&list2);
printf("List 1 after concat: \n" );
print_list(&list1);
return 0;
}
#包括
#包括
结构节点{
字符数据;
结构节点*下一步;
};
结构链表{
结构节点*头部;
};
void concat(结构链接列表*列表1,结构链接列表*列表2)
{
结构节点*tmp=list1->head;
while(tmp->next!=NULL)
tmp=tmp->next;
tmp->next=list2->head;
}
无效打印列表(结构链接列表*列表)
{
结构节点*tmp=list->head;
while(tmp!=NULL){
printf(“%c-”,tmp->data);
tmp=tmp->next;}
printf(“\n”);
}
无效打印(结构链接列表*列表)
{
结构节点*tmp=list->head;
printf(“%c\n”,tmp->data);
tmp=tmp->next;
printf(“%c\n”,tmp->data);
tmp=tmp->next;
printf(“%c\n”,tmp->data);
}
int main()
{
结构链接列表列表1、列表2;
结构节点n1、n2、n3、n4、n5;
n1.数据=‘A’;
n2.数据='B';
n3.data='C';
n4.data='D';
n5.data='E';
n1.next=&n2;
n2.next=&n3;
n4.next=&n5;
列表1.head=&n1;
列表2.head=&n4;
printf(“列表1包含:\n”);
打印列表(&list1);
concat(列表1和列表2);
printf(“concat:\n之后的列表1”);
打印列表(&list1);
返回0;
}
此处:
struct node n1,n2,n3,n4,n5;
创建五个节点而不初始化它们。C不会将局部变量初始化为null或零,因此节点的字段具有indeterimate(“垃圾”)值。稍后,您将初始化一些字段,但不会初始化列表中最后一个节点的next
字段
有几种解决方案,例如:
(1) 显式初始化最后一个节点的next
字段:
n1.next = &n2;
n2.next = &n3;
n3.next = NULL;
n4.next = &n5;
n5.next = NULL;
(2) 使用数据初始化节点,然后设置链接:
struct node n1 = {'A'};
struct node n2 = {'B'};
struct node n3 = {'C'};
struct node n4 = {'D'};
struct node n5 = {'E'};
n1.next = &n2;
n2.next = &n3;
n4.next = &n5;
初始化结构后,所有字段都将被初始化,即使没有明确给出值(如next
)。根据类型,这些字段以零或null隐式初始化。现在,在设置链接之前,您有了有效(但未连接)的节点
(3) 通过初始化定义所有内容:
struct node n5 = {'E', NULL};
struct node n4 = {'D', &n5};
struct linked_list list2 = {&n4};
struct node n3 = {'C', NULL};
struct node n2 = {'B', &n3};
struct node n1 = {'A', &n2};
struct linked_list list1 = {&n1};
现在您已经准备好了列表,但必须向后定义它,以便在引用它时知道下一个
节点
还有其他不在堆上分配内存的情况下设置链表的可能性,例如一个节点数组,但我想你明白了。首先试着理解什么是
分段错误
根据:
在计算中,分段故障(通常缩写为segfault)或访问冲突是由具有内存保护的硬件引发的故障或故障条件,通知操作系统(OS)软件试图访问内存的受限区域(内存访问冲突)
这是因为您的程序正在访问一个不打算访问的受限位置。但是为什么呢?因为在while(tmp->next!=NULL)
中,当程序遍历所有元素时,不一定会找到NULL
。因此,在这种情况下,循环不会中断,它允许循环继续,最终程序尝试访问受限位置
为了解决这个问题,在节点
结构的定义中初始化节点*Next=NULL
。比如:
struct node{
char data;
struct node* next = NULL;
};
现在next
的默认值显式设置为NULL
。因此,除非将其更改为指向另一个节点,否则它仍将保持NULL
。问题应该解决。我猜列表中的最后一个节点没有NULL
asnext
链接。您将节点创建为本地数据,而不初始化它们,这在C中意味着它们具有“垃圾”值。说struct node n1={'a'}代码>应该可以工作。next
字段隐式初始化为空指针。我在中复制粘贴了相同的内容,但没有看到任何SEGFULT。