首页 > 解决方案 > 在链表中附加一个节点 - 为什么分段错误?

问题描述

我正在 C 中实现一个具有结构的链表

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

我已经编写了 append 函数来在链表的末尾添加一个节点,如下所示,以及 display 函数来显示所有节点。但是由于我认为附加功能的一些不一致,显示会出现分段错误。这里有什么问题?我的书确实有类似的附加功能,使用 malloc。我想知道我的功能出了什么问题。

void append(struct node **q, int d)
{
    struct node *temp;
    temp = *q;
    printf("\nBegin: Address at temp = %u", temp);
    while (temp!= NULL){
        temp = temp->next;
        printf("\nTravel: Address at temp = %u", temp);
    }

    struct node p1;
    p1.data = d;
    p1.next = NULL;
    *q=&p1;
    printf("\nEnd: Address at *q = %u\n", *q);
    printf("\n*q->data = %d next = %u", (*q)->data,(*q)->next );
} 
void display(struct node *q)
{
    printf("\n");
    while (q != NULL){
        printf(" -> %d",q->data);   
        q = q->next;        
    }
}

int main(int argc, char *argv[])
{
    struct node *p;
    p = NULL; /* empty linked list */

    printf("\nNo. of elements in the Linked List = %d", count(p));
    append(&p,1);
    display(p);
    append(&p,2);
    display(p);
    printf("\nNo. of elements in the Linked List = %d", count(p));
}

输出:

No. of elements in the Linked List = 0
Begin: Address at temp = 0
End: Address at *q = 6684096

*q->data = 1 next = 0
-> 1Segmentation fault

但是,当我更换

struct node p1;
p1.data = d;
p1.next = NULL;
*q=&p1;

temp = *q;
*q = malloc(sizeof(struct node))
temp->data = d;
temp->next = NULL;

错误消失了。
有人可以解释原因吗?

标签: cpointerslinked-listmalloc

解决方案


在这里,您使用局部变量的地址,使其在离开函数后可访问:

*q=&p1;

然后你离开这个功能。
每当稍后访问它时,它将访问不再是局部变量的内存。

您需要为变量分配内存。为此使用malloc()
例如:

struct node *p1;
p1 = malloc(sizeof(*p1));
/* skipping recommended check of success/NULL */
p1->data = d;
p1->next = NULL;
*q=p1;

还有更多问题,例如您让列表以新节点开头,然后是 NULL,这会丢失/泄漏您以前的所有列表。但是最直接的问题是在一个过去的局部变量存在之后引用它的内存位置引起的。


推荐阅读