为什么 free() 释放数据但保存 next_node 值?

Why free() release data but save next_node value?

我正在使用列表进行训练,从某个时候开始我想知道 free() 函数究竟是如何工作的。我认为这将清除结构 first_node 中的数据和 next_node 值(查看代码),但只有数据值被破坏并且 next_node 仍然指向我列表中的下一个位置.为什么?

struct Data
{
    int a;
    int b;
};

struct Node
{
    struct Data* data;
    struct Node* next_node;
};

struct List
{
    struct Node* first_node;
};

void init(struct List* list)
{
    list->first_node = NULL;
}
…
struct Data* remove_first_element_from_list(struct List* list)
{
    if (list->first_node == NULL)
    {
        printf("The list is empty!\n");
        return 0;
    }
    struct Data *pointer;
    pointer = list->first_node->data;
    free(list->first_node);
    list->first_node = list->first_node->next_node;
    return pointer;
}

感谢您的解释。

Free 基本上释放指针指向的内存。在列表中,您有两个指向不同位置的指针,并且您已经释放了 data 指向的内存,而不是 next_node 指向的内存,因此该内存仍然在您的范围内。

你有未定义的行为当你

list->first_node = list->first_node->next_node

UB 是因为list->first_node不再指向分配的内存。

但是,没有说明当您调用 free 时必须清除或以其他方式修改数据。它所做的只是告诉操作系统内存再次可供某人分配。这就是为什么你仍然可以使用指针,这是 UB 的特点之一,行为是 undefined,有时 seem 可以工作实际上这是一个非常严重的问题。

free 只是释放内存以允许再次使用它(例如,在对 malloc 的另一个调用中)。

它不清除内存。因此,如果您在免费通话后使用它,您 可能 获得相同的值。

在释放内存后使用内存,正如您在调用 free 之后的行中所做的那样 "undefined behaviour" 有时可能会起作用,并且有时不起作用 - 每次您 运行 程序时结果可能会有所不同。所以 - 不要这样做!

free不需要擦除任何东西——那样会浪费时间——它只是把你还给的内存块标记为"free to be recycled",把它加回一些空闲的将在下一个 malloc 检查的块列表。内存块的一个或两个成员已被修改的事实只是一个实现细节 - 无论如何你不应该窥视释放块,因为分配器可以自由取消映射它们的内存,从而给你一个段错误(更一般,查看释放内存的内容是 "undefined behavior",即任何事情都可能发生)。