当我在循环中调用该函数时,将新节点插入单链表不起作用

Inserting a new node to a singly linked list doesnt work when i call the function in a loop

我试图追加一个节点到列表的末尾,所以我写了一个简单的append_node函数。这个函数正常工作,但是当我使用 for loop 时,一个带有 undefined value 的额外节点被存储到 head node.

代码如下:

int main() {
    linked_list *list;

    append_node(&list, 4);
    append_node(&list, 20);
    append_node(&list, 200);

    print_linked_list(list);    // 4 20 200
                                //prints just fine
}

上面的代码工作正常,但是当我在下面这样做时:

int main() {
    linked_list *list;

    for (int i = 0; i < 5; i++)
        append_node(&list, i);

    print_linked_list(list);   // 11342689 0 1 2 3 4
                               // prints a extra undefined node here at the head 
}

预期结果:0 1 2 3 4 实际结果:11342689 0 1 2 3 4

这里是 append_node 函数:

void append_node(linked_list **head_ref, int value) {
    linked_list *current = *head_ref;

    linked_list *new_node = (linked_list *)malloc(sizeof(linked_list));
    new_node->node_value = value;
    new_node->next_node = NULL;

    if (*head_ref == NULL) {
        *head_ref = new_node;
        return;
    }

    while (current->next_node)
        current = current->next_node;

    current->next_node = new_node;
    return;
}

每当我使用 loop 时,列表都会得到一个 具有未定义值的新头 。列表的其余部分似乎是正确的。我不知道为什么会这样。谁能告诉我吗? 提前致谢:)

您应该将 linked_list *list 初始化为 NULL,它应该可以正常工作。

具有自动存储持续时间的变量不会被隐式初始化。本声明中的 Si

linked_list *list ;

声明了指针list,其值不确定。

因此程序具有未定义的行为。

你必须像

一样明确地初始化指针
linked_list *list = NULL;

除此之外,函数 append_node 可以定义得更简单、更安全,因为指针 list 是通过引用传递给函数的。

给你。

int append_node( linked_list **head_ref, int value )
{
    linked_list *new_node = malloc( sizeof( linked_list ) );
    int success = new_node != NULL;

    if ( success )
    {
        new_node->node_value = value;
        new_node->next_node  = NULL;

        while ( *head_ref != NULL )
        {
            head_ref = &( *head_ref )->next_node;
        }

        *head_ref = new_node;
    }

    return success;
}

main 中的 list 变量未初始化。在这两种情况下,代码都有未定义的行为。未定义的行为有时会产生预期的行为,有时不会。为这两个函数生成的代码是不同的,所以有可能 list 存储的位置在第一种情况下恰好是一个空指针,而不是第二种情况。

恐怕即使在启用额外警告 (gcc -Wall -Wextra -Werror) 的情况下编译您的程序也不会发现此错误。

这是修改后的版本:

#include <stdio.h>
#include <stdlib.h>

typedef struct linked_list {
    struct linked_list *next_node;
    int node_value;
} linked_list;

void print_linked_list(const linked_list *list) {
    while (list) {
        printf("%d ", list->node_value);
    }
    printf("\n");
}

linked_list *append_node(linked_list **head_ref, int value) {
    linked_list *current = *head_ref;
    linked_list *new_node = malloc(sizeof(linked_list));
    if (new_node) {
        new_node->node_value = value;
        new_node->next_node = NULL;
        if (current == NULL) {
            *head_ref = new_node;
        } else {
            while (current->next_node)
                current = current->next_node;
            current->next_node = new_node;
        }
    }
    return new_node;   // if memory allocation failed, the function will return NULL
}

int main() {
    linked_list *list = NULL;

    for (int i = 0; i < 5; i++)
        append_node(&list, i);

    print_linked_list(list);
    return 0;
}