All C implementations use a call stack. So a local variable is on that stack (or in a register) and disappears when the called function returns.
In theory, C does not require any call stack. In practice, all C implementations use one.
In fact, a local variable is lost (so disappears) when the block (between braces) declaring it is exited. Actually, the slot on the call frame may be reused, or the variable sits in a register which is often reused for other means.
When coding in C you should think as if every local variable disappears when its block is exited. The compiler is free to implement that abstraction as it wants (generally, using a call stack, or keeping that variable in some register or some other area which will be reused later).
Notice that in your example both x
and loc
are local variables. But loc
contains a pointer to a memory zone on the heap. And that zone is released by free
Read about undefined behavior, e.g.
// WRONG CODE!
int* p = 0;
{
int y = 23;
p = &y;
};
int z = *p; // undefined behavior
Here y
is a local variable to the block in braces. You store its address in p
. When you dereference that address to put its content into z
you have an undefined behavior and the implementation can do anything (including destroying the universe, or exploding your computer) and still be conformant to the specification of C.
What happens in reality is unpredictable without knowing the specific implementation and environment. Actually, and this is bad for you, the above code might not even "fault" and something could be stored in z
.