
There is said to have 3 types of memory allocations:
Static allocation, Dynamic allocation and Automatic/Stack allocation
Static allocation:
Memory is allocated during compile time. Variables with global scope or declared with the static keyword fall under this category. The size and address of the variable are determined before the program runs, and the memory is reserved throughout the program's lifetime.
Dynamic allocation:
Memory is allocated at runtime, typically from the heap using functions like malloc(), calloc(), or realloc(). This memory must be manually managed by the programmer.
Automatic/Stack Allocation:
Local variables (like i in your example) are allocated at runtime when the function is called but on the stack. This is sometimes referred to as automatic allocation because memory is automatically freed when the function returns. However, this isn't the same as dynamic memory allocation in the sense of the heap.
All those variables with static storage duration (ie., static variables and global variables) will be allocated memory inside static memory. Thier sizes are known during compilation itself. For further clarifications, check this
However, although the auto variables are allocated automatically at runtime into the stack, the stack's total size is fixed at the compile time, in most cases. This means, the total stack size is fixed at compile time through compiler options or system settings. But the automatic memory allocation will be happening at the runtime only, when the corresponding function is called. Thus eventhough the stack grows downwards, the total size allocated for stack is fixed at compile time and once the limit is reached, further attempts to push the data into the stack, will lead to stack overflow.
Now, your question's direct answer is, when a function with a VLA is called, the size of the array is computed at runtime, and the stack pointer is adjusted to allocate the required space. The stack frame is expanded dynamically to accommodate the size of the VLA.Once the function returns, the stack pointer is adjusted to free the space, just like with regular local variables.
Limitations of VLA:
VLAs can increase the risk of stack overflow, especially if a large VLA size is provided at runtime, because the total stack size is still limited (usually a few MBs). Unlike heap allocation (which is much larger), the stack has relatively small limits.
Your example comes under automatic memory allocation (auto variable with runtime memory allocation in stack).