不带 malloc 的链表 [duplicate]

Linked list without malloc [duplicate]

提问人:Anh Duc Nguyen 提问时间:11/9/2023 最后编辑:Vlad from MoscowAnh Duc Nguyen 更新时间:11/9/2023 访问量:91

问:

我自己也开始学习 C,根据《Programming in C (4th Edition)》一书,作者定义了一个链表如下:

struct entry
{
    int value;
    struct entry *next;
};

struct entry *createNewLinkList(void)
{
    struct entry n1, n2, n3;
    struct entry *list_pointer = &n1;

    n1.value = 100;
    n1.next = &n2;
    n2.value = 200;
    n2.next = &n3;
    n3.value = 300;
    n3.next = NULL;
    return list_pointer;
}

void print_linked_list(struct entry *linked_list)
{
    struct entry *current = linked_list;
    while (current != NULL)
    {
        printf("%d\n", current->value);
        current = current->next;
    }
    printf("\n");
}

int main(void)
{
    struct entry *linked_list = createNewLinkList(); //DEBUG: This line is fine linked_list: {value:100, next:0x000000016fdff200}
    printf("Original list \n");
    print_linked_list(linked_list);   //DEBUG: it is wrong after entering this line linked_list:{value:1876947504, next:0x8b7a000100003f48}
}

我不明白为什么刚刚的值变成了某个地址。linked_list

如果我像这样使用 malloc 创建链表,它将起作用:

struct entry *createNewLinkList(void)
{
    struct entry *n1 = (struct entry *)malloc(sizeof(struct entry));
    struct entry *n2 = (struct entry *)malloc(sizeof(struct entry));
    struct entry *n3 = (struct entry *)malloc(sizeof(struct entry));

    n1->value = 100;
    n1->next = n2;

    n2->value = 200;
    n2->next = n3;

    n3->value = 300;
    n3->next = NULL;
    return n1;
}

先谢谢你,

c malloc 未定义行为 单链列表 存储持续时间

评论

1赞 Guillius 11/9/2023
是书中的第一个代码示例吗?因为在我看来,一些局部变量是在函数 createNewLinkList() 中定义的,但它们的作用域将结束,所以当你在 main() 函数中使用此函数返回的指针时,你不再能保证数据仍然在内存中的那个位置。
3赞 Marco Bonelli 11/9/2023
我希望你从书中复制了错误的例子......否则,为了上帝的爱,现在就把它扔进垃圾桶:')
3赞 Jabberwocky 11/9/2023
如果这个例子实际上是书中的逐字记录,那就烧掉这本书。
3赞 Lundin 11/9/2023
(无论如何,这本书可能属于垃圾桶,因为在下一章中,他将通过在 main() 中声明函数原型来教授如何调用函数。
1赞 Jabberwocky 11/9/2023
我只是看了一眼这本书。恕我直言,这绝对是废话。

答:

3赞 Vlad from Moscow 11/9/2023 #1

书中的程序(如果确实是书中的代码)具有未定义的行为。

该函数返回一个指向具有自动存储持续时间 () 的本地对象的指针,该对象在退出函数后将不处于活动状态(以及通过指针链接的其他局部变量)createNewLinkListn1

struct entry *createNewLinkList(void)
{
    struct entry n1, n2, n3;
    struct entry *list_pointer = &n1;

    n1.value = 100;
    n1.next = &n2;
    n2.value = 200;
    n2.next = &n3;
    n3.value = 300;
    n3.next = NULL;
    return list_pointer;
}

因此,在函数中取消引用指针(以及存储在结构的数据成员中的其他指针)nextprint_linked_list

void print_linked_list(struct entry *linked_list)
{
    struct entry *current = linked_list;
    while (current != NULL)
    {
        printf("%d\n", current->value);
        current = current->next;
    }
    printf("\n");
}

调用未定义的行为。

如果变量 , 具有静态存储持续时间,即如果它们被声明为n1n2n3

static struct entry n1, n2, n3;

评论

0赞 Anh Duc Nguyen 11/9/2023
感谢您的解释,我开始的错误;)
1赞 Vlad from Moscow 11/9/2023
@AnhDucNguyen完全没有。我们,初学者,应该互相帮助:)