free() 是否将内存清零? [英] Is free() zeroing out memory?

查看:60
本文介绍了free() 是否将内存清零?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

直到今天,我一直相信在内存空间上调用 free() 会释放它以供进一步分配,无需任何其他修改.特别是,考虑到这个问题明确指出 free() 不会将内存归零.

Until today I lived in belief that calling free() on memory space releases it for further allocation without any other modifications. Especially, considering this SO question that clearly states that free() DOESN'T zero out memory.

然而,让我们考虑一下这段代码(test.c):

Yet, let's consider this piece of code (test.c):

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

int main()
{
    int* pointer;

    if (NULL == (pointer = malloc(sizeof(*pointer))))
        return EXIT_FAILURE;

    *pointer = 1337;

    printf("Before free(): %p, %d
", pointer, *pointer);

    free(pointer);

    printf("After free(): %p, %d
", pointer, *pointer);

    return EXIT_SUCCESS;
}

编译(GCC 和 Clang):

Compiling (both GCC and Clang):

gcc test.c -o test_gcc
clang test.c -o test_clang

结果:

$ ./test_gcc 
Before free(): 0x719010, 1337
After free(): 0x719010, 0
$ ./test_clang
Before free: 0x19d2010, 1337
After free: 0x19d2010, 0

为什么会这样?我一直生活在谎言中还是我误解了一些基本概念?或者有更好的解释吗?

Why is it so? Was I living in a lie all this time or did I misunderstand some basic concepts? Or is there a better explanation?

一些技术信息:

Linux 4.0.1-1-ARCH x86_64
gcc version 4.9.2 20150304 (prerelease) (GCC)
clang version 3.6.0 (tags/RELEASE_360/final)

推荐答案

对于您的问题,没有唯一确定的答案.

There's no single definitive answer to your question.

  • 首先,被释放块的外部行为将取决于它是被释放到系统中还是作为一个空闲块存储在进程或 C 运行时库的内部内存池中.在现代操作系统中,您的程序将无法访问返回系统"的内存,这意味着它是否被清零的问题没有实际意义.

(其余的适用于保留在内部内存池中的块.)

(The rest applies to the blocks retained in the internal memory pool.)

  • 其次,用任何特定值填充已释放的内存几乎没有意义(因为您不应该访问它),而这种操作的性能成本可能相当可观.这就是为什么大多数实现不做任何释放内存的事情.

  • Secondly, there's little sense in filling freed memory with any specific value (since you are not supposed to access it), while the performance cost of such operation might be considerable. Which is why most implementations don't do anything to freed memory.

第三,在调试阶段,用一些预先确定的垃圾值填充释放的内存对于捕获错误(如访问已经释放的内存)很有用,这就是为什么许多标准库的调试实现会用一些预先确定的值或模式.(零,顺便说一句,不是这种价值的最佳选择.像 0xDEADBABE 模式这样的东西更有意义.)但同样,这仅在库的调试版本中完成,其中性能影响是不是问题.

Thirdly, at debugging stage filling freed memory with some pre-determined garbage value can be useful in catching errors (like access to already freed memory), which is why many debug implementations of standard library will fill freed memory with some pre-determined value or pattern. (Zero, BTW, is not the best choice for such value. Something like 0xDEADBABE pattern makes a lot more sense.) But again, this is only done in debug versions of the library, where performance impact is not an issue.

第四,堆内存管理的许多(最)流行的实现将使用释放块的一部分用于其内部目的,即在那里存储一些有意义的值.这意味着块的那个区域被 free 修改.但一般不会归零".

Fourthly, many (most) popular implementations of heap memory management will use a portion of the freed block for its internal purposes, i.e. store some meaningful values there. Which means that that area of the block is modified by free. But generally it is not "zeroed".

当然,所有这些都在很大程度上依赖于实现.

And all this is, of course, heavily implementation-dependent.

总的来说,您最初的想法是完全正确的:在代码的发布版本中,释放的内存块不会受到任何块范围的修改.

In general, your original belief is perfectly correct: in the release version of the code a freed memory block is not subjected to any block-wide modifications.

这篇关于free() 是否将内存清零?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆