Note. Listed below are implementation details. This standard does not apply to this standard.
The accident is not caused by the distribution of space. The accident is caused by writing to pages that are not writable, or reading from pages that are not readable.
You can see that declarations do not really need to read or write any memory, not necessarily:
int i;
But if it is initialized, you need to write the value:
int i = 0;
This causes a malfunction. Note that the exact behavior will depend on the compiler you are using and the optimization settings. Different compilers will distribute the variables differently, and the optimizing compiler usually removes both i and foo from the whole function, since they are not needed. Some compilers also initialize variables to garbage values โโin specific configurations to aid in debugging.
The allocation of stack space is simply related to changing the stack pointer, which is a register. If you allocate too much stack space, the stack pointer points to an invalid memory region, and the program will segfault when it tries to read or write to these addresses. Most operating systems have "protective pages", so the actual memory will not be placed next to the stack, ensuring that the program will successfully crash in most scenarios.
Here are some results from Godbolt :
main: push rbp mov rbp, rsp sub rsp, 1073741720 ; allocate space for locals mov DWORD PTR [rbp-4], 0 ; initialize i = 0 mov eax, 0 ; return value = 0 leave ret
Please note that this version is not crashing because i is pushed to the top of the stack (which grows down). If i is placed at the bottom of the stack, this is most likely a failure. The compiler is free to push variables onto the stack in any order, so if it actually crashes will depend heavily on the particular compiler used.
You can also see more clearly why the distribution will not fail: