Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/62.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C将链表结构传递给函数_C_Struct_Linked List_Segmentation Fault - Fatal编程技术网

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

我用C实现了一个链表

问题是,每当我尝试使用函数
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
as
next
链接。您将节点创建为本地数据,而不初始化它们,这在C中意味着它们具有“垃圾”值。说
struct node n1={'a'}应该可以工作。
next
字段隐式初始化为空指针。我在中复制粘贴了相同的内容,但没有看到任何SEGFULT。