Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
224 views
in Technique[技术] by (71.8m points)

c - Is free() zeroing out memory?

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

    free(pointer);

    printf("After free(): %p, %d
", 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)
question from:https://stackoverflow.com/questions/30683519/is-free-zeroing-out-memory

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...