是免费的()清零内存? [英] Is free() zeroing out memory?

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

问题描述

直到今天,我仍然相信在内存空间调用 free()会释放它进行进一步分配,而无需进行任何其他修改。尤其是,考虑这个SO问题这明确指出 free()不会将内存清零。然而,让我们考虑这段代码(test.c):

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

int main()
{
int *指针;
$ b $ if(NULL ==(pointer = malloc(sizeof(* pointer))))
return EXIT_FAILURE;

* pointer = 1337;

printf(free():%p,%d \\\
,指针,*指针);

free(指针);

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

return EXIT_SUCCESS;

$ / code>

编译(包括GCC和Clang):

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

结果:

  $ ./test_gcc 
免费之前):0x719010,1337
免费后():0x719010,0
$ ./test_clang
免费前:0x19d2010,1337
免费后:0x19d2010,0

为何如此?我是否一直生活在谎言中,还是误解了一些基本概念?还是有更好的解释?



一些技术信息:

  Linux 4.0.1-1-ARCH x86_64 
gcc版本4.9.2 20150304(预发布)(GCC)
铿锵声3.6.0版(tags / RELEASE_360 / final)

$ b $

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


(其余的适用于保留在内部存储池中的块)。其次,在释放任何特定的值(因为你不应该访问它)而没有任何意义,而这种操作的性能成本可能相当大。这就是为什么大多数实现没有做任何事情来释放内存的原因。第三,在调试阶段,使用一些预定义的垃圾值填充释放的内存可能是有用的在捕获错误(比如访问已经释放的内存)时,这就是为什么标准库的许多调试实现会用一些预定值或模式填充释放的内存。 (Zero,BTW,不是这种值的最佳选择,类似于 0xDEADBABE 模式更有意义)。但是,这只是在调试版本的第四,堆存储器管理的许多(大多数)流行实现将使用一部分释放的块作为它的存储区,因为它的性能影响不是问题。 内部目的,即在那里存储一些有意义的价值。这意味着块的该区域被 free 修改。但通常它不会被调零。




当然,这一切依赖于实施。 / p>

一般而言,您的原始信念是完全正确的:在发行版本的代码中,释放的内存块不会受到任何块范围的修改。 b $ b

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.

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\n", pointer, *pointer);

    free(pointer);

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

    return EXIT_SUCCESS;
}

Compiling (both GCC and Clang):

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

Result:

$ ./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?

Some technical info:

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.

  • Firstly, the external behavior of a freed block will depend on whether it was released to the system or stored as a free block in the internal memory pool of the process or C runtime library. In modern OSes the memory "returned to the system" will become inaccessible to your program, which means that the question of whether it was zeroed-out or not is moot.

(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.

  • 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.

  • 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.

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

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