views:

144

answers:

4

In the following code segment, after free(x), why does y becomes 0?

As per my understanding, the memory in the heap that was being pointed to by x, and is still being pointed by y, hasn't been allocated to someone else, so how can it change to 0?

And moreover, I don't think it is free(x) that changed it to 0.

Any comments?

#include <stdio.h>

int main ( int argc, char *argv[] )
{
        int *y = NULL;
        int *x = NULL;

        x = malloc(4);
        *x = 5;

        y = x;
        printf("[%d]\n", *y); //prints 5

        free(x);

        printf("[%d]\n", *y); //why doesn't print 5?, prints 0 instead

        return 0;
}
+4  A: 

What is done in free depends on the implementation. It is not prohibited to zero out the memory after it's freed.

And what you're doing is undefined behavior.

KennyTM
+11  A: 

This is undefined behavior, explanations are just speculation.

I can speculate that maybe you are running a debug version of the C library, and that the debug version of free() does zero the pointed area.

Didier Trosset
+1, absolutely. The question is actually meaningless because there is no defined answer.
Cruachan
Except that usually debug heap managers will explicitly fill freed memory with something *other than* zero.
Michael Burr
@Cruachan - Not quite meaningless, the answer quite definitive, its undefined. Undefined is undefined.
Tim Post
+1  A: 

Doesn't y points to the same address as x, after line

y = x;

If you free x, you will also free the memory pointed by y.

If you are wondering why it prints '0', that undefined behavior, but I've seen it as a practice before, that some programmers, sets the freed area to '0'.

Download this video called "Binky the pointer fun video" (it's not a joke, actually is very educative), and you'll get pointers better.

Andrei Ciobanu
I understand what are dangling pointers!, I was just trying to understand y=0 behavior.
Aman Jain
same code example used in the video -http://cslibrary.stanford.edu/106/
jschmier
+2  A: 

The call to free() will put the memory block that had been allocated by malloc() back onto data structures that the C run time maintains for the heap (in this case something that might be called the 'free-list).

Manipulating the heap data structures might incidentally change what was being pointed to by y (since the program doesn't won the memory anymore, it has no reason to believe the memory shouldn't change).

In a non-debug build of the program, the runtime typically won't do anything specifically to invalidate freed memory, but as I mentioned, it may still make changes as a result of its own bookkeeping (though since the memory doesn't belong to the caller anymore, the runtime allowed to do whatever it likes).

In a debug build, the runtime will probably explicitly overwrite the memory to a value that is likely to be invalid if the program does use it in the hopes that it will cause a problem that identifies the problem more readily. Usually the value used to overwrite the freed memory block isn't zero, since zero will often not expose a bug (ie., NULL pointer checks will cause the code to 'handle' the invalid memory access). For example, MSVC's debug heap manager will overwrite freed memory with the value 0xDD (see http://stackoverflow.com/questions/370195/when-and-why-will-an-os-initialise-memory-to-0xcd-0xdd-etc-on-malloc-free-new/370362#370362 for more details).

Michael Burr