Interesting question. Your code is likely to work (or seem to work) on some platforms and to fail on others.
The reason your code seems to work is that the memory the function f()
reserves on the stack is released but not erased when f()
returns. Being released, the memory becomes available for other functions to use; but it might not be overwritten until another function actually does use it.
Some others here are correctly pointing out that your code evokes undefined behavior, and technically that is true. However, there is a reason you are getting the particular undefined behavior you are getting, and that is what my answer is about.
On some platforms, including the x86, after f()
releases the memory of v[]
, the first memory to be reused will normally be the memory that used to hold v[999999]
. It may be a long time before the memory that holds v[0]
gets reused. Hence, the data from v[7]
is spuriously still present.
There is at least one more wrinkle. Some implementations, using some settings, may overwrite all released memory immediately with random data, to guard against security risks. (What if v[]
held a password, for example? The random data would wipe it safely away.)