【问题标题】:What happens to the memory which is freed after being allocated by malloc()?malloc() 分配后释放的内存会怎样?
【发布时间】:2016-04-22 15:03:13
【问题描述】:

使用 malloc() 分配的内存在被释放后究竟会发生什么? 假设我执行以下操作...

int main(){
    int * arr;
    arr=(int*) malloc(sizeof(int)*20);
    int i;
    for(i=0;i<20;i++) arr[i]=2*i+1;
    int * tmp=arr;
    for(i=0;i<20;i++) printf("%d ",*(tmp+i));
    printf("\n");
    free(arr);
    for(i=0;i<20;i++) printf("%d ",*(tmp+i));
    return 0;
}

我得到了输出...

1 3 5 7 9 11 13 15 17 19 21 23 25 27 29 31 33 35 37 39 
0 0 5 7 9 11 13 15 17 19 21 23 25 27 29 31 33 35 37 39 

为什么前两个条目会改变(而其他条目没有)?

【问题讨论】:

  • 一旦内存被释放,它可以被重新使用。仅仅因为您自己的代码没有显式更改该内存,并不意味着 C 内部更深层次的其他内容无法执行自己的 malloc 并获取部分/全部释放的块。
  • 如果您有时间,请阅读此stackoverflow.com/a/6445794/434551。之后理解指针会容易很多。
  • 释放的块可能通过 free() 调用加载了堆管理元数据。
  • "为什么前两个条目会改变" --> 除了好奇之外,您为什么还要想知道发生了什么?为什么数据保持不变或发生变化很重要?
  • 请注意,“未定义行为”并不意味着“随机”。它的意思是“这取决于我们不应该关心的一些代码”。是的,这个问题背后可能有一个原因,但考虑它是不合理的。

标签: c memory memory-management free


【解决方案1】:

为什么前两个条目会改变(而其他条目没有)?

TL;DR undefined behavior.


一旦您在先前由malloc() 返回的指针上调用了free(),则该指针在您的程序上下文中不再有效。尝试使用它会调用undefined behavior。

说到实际内存会发生什么,嗯,这也取决于环境。调用free() 只是通知下层(操作系统/内存管理器)可以回收和重用内存如果需要。没有强制内存位置必须被清理(归零)或类似的东西。

【讨论】:

  • 那么内存有没有可能保持不变?
  • @samurdhilbk 我已经更新了我的答案,请看一下。如果您有任何疑问,请告诉我。
  • 是的,内存很可能没有改变——为什么系统会浪费时间对它做任何事情呢?唯一重要的是它不再属于你,所以你不能使用它。
【解决方案2】:

malloc、free 和 realloc 函数管理传统上称为“堆”的内存区域。 malloc 和 realloc 选择堆的一个区域,将其标记为“正在使用”,并将指向内存的指针返回给您。 free 将内存返回到堆中,以供将来的 malloc 和 free 调用使用。

当free 将内存返回到堆中,并将其标记为不再被您的程序使用时,可能是它标记它的方式之一涉及在内存中设置位。在您的情况下,这就是您的某些数组值发生变化的原因。

(当然,你不能依赖这个。其他实现可能完全没有改变现在释放的内存。其他人可能已经完全删除了它。而且你的程序也有可能在尝试打印时崩溃释放内存后将其取出,因为您当然不应该这样做。)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-06-15
    • 2023-01-21
    • 2010-10-26
    • 2011-10-24
    • 2016-11-16
    • 1970-01-01
    • 2012-01-07
    • 2021-04-28
    相关资源
    最近更新 更多