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)
Differences in delete and free are:It destroys the memory at the runtime. It should only be used either for the pointers pointing to the memory allocated using the new operator or for a NULL pointer. It should only be used either for the pointers pointing to the memory allocated using malloc() or for a NULL pointer.
free() just declares, to the language implementation or operating system, that the memory is no longer required.
The data in memory doesn't disappear or anything like that; the values may indeed still be there after a free() , though attempting to read from freed memory is undefined behaviour.
No, Linux does not zero its menory after releasing it. Most libraries implement zeroing the memory while allocating it, but this is programming language dependent and can be overridden.
There's no single definitive answer to your question.
(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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With