【问题标题】:why can't I initialize a linked list like this?为什么我不能像这样初始化一个链表?
【发布时间】:2020-10-22 06:06:41
【问题描述】:

LinkedList.c

#include "stdio.h"
#include "stdlib.h"


struct ListNode
{
    int val;
    struct ListNode *next;
};

int main()
{
    int a[] = {1, 2, 3};
    struct ListNode *head = malloc(sizeof(struct ListNode));
    head->next = NULL;
    struct ListNode *rear = head;
    for (int i = 0; i < 3; i++)
    {
        struct ListNode s;
        s.val = a[i];
        s.next = rear->next;
        rear->next = &s;
        rear = &s;
    }
    struct ListNode *tmp = head;
    head = head->next;
    free(tmp);


    //display
    while (head != NULL)
    {
        printf("%d ",(*head).val);
        head = head->next;
    }

    return 0;
}

如果我改变句子“struct ListNode s;”到“struct ListNode *s=malloc(sizeof(struct ListNode));”并使用“->”而不是“.”,它会起作用。

【问题讨论】:

  • 在添加节点的循环中,您有struct ListNode s;。这将 s 定义为循环内的 local 变量。每次迭代都会结束s 的生命周期,并在下一次迭代开始时创建一个全新的s。一旦其生命周期结束,任何指向该变量的指针都将变为无效。您还需要为添加的节点进行动态分配(几乎任何体面的书籍、教程或课程都应该提到或至少显示出来)。
  • 感谢您的回复。我不知道我的理解是否正确:一个局部变量会被自动释放,就像使用 free() 函数一样。因此,当局部变量在循环内时,它将在循环外被销毁。但是如果我使用'malloc()',它将一直有效,直到我使用'free()'。
  • 你为堆分配的数据的生命周期(使用malloc)永远不会结束,在你将指向它的指针传递给free之前它确实是有效的。
  • 好的,我明白了。非常感谢。

标签: c linked-list malloc


【解决方案1】:

正如 cmets 中所指出的,您正面临此问题,因为您在列表创建循环中创建的 ListNode 是一个仅限于循环范围的局部变量。它只存在于那个范围内(对于那个特定的迭代)。您应该使用malloc 分配ListNode 并使用free 在您使用完列表后为您的节点取消分配内存。我对您的列表创建循环做了一些小改动:

for (int i = 0; i < 3; i++) {
    struct ListNode *s = malloc(sizeof(struct ListNode));
    s->val = a[i];
    s->next = rear->next;
    rear->next = s;
    rear = s;
}

当我运行它时,我能够看到预期的结果:

src : $ gcc initializelinkedlist.c 
src : $ ./a.out 
1 2 3

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-02-09
    • 1970-01-01
    • 2019-07-13
    • 2019-06-28
    • 2012-05-17
    • 2022-06-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多