【问题标题】:Working of free() in C [duplicate]在 C 中使用 free() [重复]
【发布时间】:2016-03-16 12:50:45
【问题描述】:

我对 C 中的 free() 函数的工作原理有些理解。顾名思义,think free() 所做的就是释放作为参数传递的地址处的内存。然后我尝试了以下代码:

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

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

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

int main()
{
    struct node *first, *second, *temp;
    first = malloc(sizeof(struct node));
    second = malloc(sizeof(struct node));
    temp = first;
    first->data = 1;
    first->next = second;
    second->data = 2;
    second->next = NULL;
    free(first);
    while(temp!=NULL)
    {
        printf("%d\n", temp->data);
        temp = temp->next;
    }
    return 0;
}

以上是链表的一个非常基本的实现。我创建了两个节点,即第一个和第二个,输入数据并将它们链接在一起。然后我“释放”了第一个节点,并尝试打印链接列表。 我得到以下输出:

0
2

那么,这是我的问题,为什么要打印第二个节点?如果第一个节点被释放,那么所有数据和下一个指针都应该被删除。即使我这样做了

temp = first;

我只是将地址从 first 复制到 temp。当我首先释放时,存储在那里的任何内容都应该被销毁,包括第二个节点的地址。那我怎么还能打印第二个节点呢?

【问题讨论】:

  • UB 和多副本 :(
  • 当您执行 malloc() 时,将从堆中为您的程序分配内存.. 一旦您使用 free() 释放内存,内存将返回给可用块,以便其他程序可以使用那段记忆。它不会破坏写入该内存的数据,除非它会被其他程序覆盖。
  • 您可能很恼火,为什么 temp->data 似乎被归零而 temp->next 却没有。这只是由于元数据被写入free() 上分配的内存块的(数据部分)(所谓的free-list)。并且不是免费系统地销毁数据的机制。

标签: c linked-list free


【解决方案1】:

问题在于您的假设:

如果第一个节点被释放,那么所有的数据和下一个指针 应该被删除了。

您可以释放第一个节点,然后该内存将返回到堆中。它不会(必然)以任何方式被修改。在您的示例中,指向第二个节点的指针恰好保持不变,因此您仍然可以迭代它。这就是您能够打印列表中的第一个和第二个数字的方式。

基本上,free() 所做的只是说“这个进程不再关心这块内存”。然后操作系统或其他东西可以使用它。下次你使用 malloc() 时,它可能会再次给你同样的内存块。

当然,这都是未定义的行为。这意味着它会愉快地运行,直到不再运行为止。

【讨论】:

  • 你为什么回答一个非常明显的重复?
  • 该问题未被标记为重复。我做错了吗?
  • 如果你看看它下面的 cmets,你会发现它之前已经讨论过了。该问题目前处于 4 票接近的状态(还有 1 票以欺骗方式结束)(尽管您看不到这一点)。在这种情况下,如果多人指出它是重复的,你应该避免回答。
  • 好吧,现在我知道了。谢谢
猜你喜欢
  • 1970-01-01
  • 2017-01-16
  • 1970-01-01
  • 2011-05-25
  • 2021-10-09
  • 1970-01-01
  • 2016-01-08
  • 2021-03-28
  • 1970-01-01
相关资源
最近更新 更多