As for the area, it is easiest to think that C is compiled into a series of manipulations with the register and memory, such structures as blocks, for-loops, if-statements, structs, etc., have no meaning after compilation, these are just abstractions that allow you as a programmer to maintain your judgment.
As for example and memory, this is my attempt to explain this.
As everyone says, you use specific compilers for specific implementations of the standard undefined action. To understand how this works, you can think about the program you are writing with two memories, a heap and a stack. As an example, char *foo = malloc(50); allocates memory on the heap, and char foo[] = "Foo" allocates it on the stack. A stack is a memory that remembers what you are doing and contains a long list of stack frames, each function call adds a frame, and each return pops up. A heap is another kind of memory.
To illustrate this, we have this program:
int *ptr; int func() { int abc = 123; ptr = &abc; return 0; } int func1() { int def; printf("func1() :: *abc=%i\n", *ptr); def = 200; return 0; } int main() { func(); printf("main() :: *ptr=%i\n", *ptr); func1(); printf("main() :: *ptr=%i\n", *ptr); }
And the following will happen on the stack ( - - undefined / unused memory, > on the left is where your program is currently running, X is the data):
|-----| |-----| |-----|
When we inject main() , it pushes the stack stack onto the stack:
|-----| |-----| >|XXXXX| <- This is where all memory needed to execute main() is.
Then you call func() , which in the memory needed to execute contains the integer 123 .
|-----| >|XX123| <- This is the stack frame for func() |XXXXX| <- Still the stack frame for main()
func() sets the global *ptr to the address of an integer on the stack. This means that when func() returns (and the memory is not cleared, as this will be a waste of processor cycles), the value remains
|-----| |--123| >|XXXXX| <- main()
and you can still reference *ptr until you call the following function
|-----| >|XXXXX| <- This is the stack frame for func1() |XXXXX|
Now *ptr some random value will appear ... but you can still access the memory position and change it. (If func() and func1() each defines only one local integer in its scope, it is very likely that *ptr will also point to this integer in func1() )
Bonus
I did not test the program, but I would assume that it will output something like this:
main() :: *ptr=123 func1() :: *ptr=<some random values> main() :: *ptr=<possibly 200, could be something else>