How are allocated arrays declared in a loop?

70 Views Asked by At

I'm puzzled over this function.

int i;
for(i = 1; i<10; i++){
        int arr[i];
        printf("%d\n",sizeof(arr));
    }

return 0;

How can the space grow in a bounded (by ESP) stack memory? Is there a sort of compilation trick?

EDIT for explanation: Shouldn't the stack be something like that?

0  ---> val of i uninitialized
-4 ---> arr[0] uninitialized

and after the first loop

0  ---> val of i uninitialized
-4 ---> arr[1] uninitialized
-8 ---> arr[0] uninitialized

I'm tempted to say: is ESP moving below each iteration of the loop?

3

There are 3 best solutions below

2
On BEST ANSWER

On every loop there is allocated stack for the array and then dealocated.

A bit different example

#include "stdio.h"
#include "string.h"

int h(int x) 
{
    for(int i = 1; i<x; i++){
            char arr[i];
            memset(arr, i, sizeof(arr));
            printf("%d\n",sizeof(arr));
        }
    return 0;
}

int main()
{
   h(50);
}

in the compiled code


.LC0:
        .string "%d\n"
h:
        push    rbp
        mov     rbp, rsp
        push    r13
        push    r12
        mov     r12d, edi
        push    rbx
        mov     ebx, 1
        push    rax
.L2:
        cmp     r12d, ebx
        jle     .L6
        lea     rax, [rbx+15]
        mov     r13, rsp
        mov     ecx, ebx
        mov     rsi, rbx
        and     rax, -16
        sub     rsp, rax
        mov     eax, ebx
        inc     rbx
        mov     rdi, rsp
        rep stosb
        mov     edi, OFFSET FLAT:.LC0
        xor     eax, eax
        call    printf
        mov     rsp, r13
        jmp     .L2
.L6:
        lea     rsp, [rbp-24]
        xor     eax, eax
        pop     rbx
        pop     r12
        pop     r13
        pop     rbp
        ret
main:
        push    rax
        mov     edi, 50
        call    h
        xor     eax, eax
        pop     rdx
        ret

lines 15,19 & 20 allocate the space and thew line 28 deallocates the space for the array

https://godbolt.org/z/msgrc2

0
On

How can the space grow in a bounded size stack memory?

You refer to the space of char arr - its space does not grow. It's a local variable inside the scope of the for loop. So everytime the loop has a new i it's a brand new char arr.

0
On

Is there a sort of compilation trick?

Yes, sort of. It uses VLAs (https://en.wikipedia.org/wiki/Variable-length_array)

Godbolt is very useful for inspecting things like this:

https://godbolt.org/z/_uR9Ac

As you can see the -Wvla warning is indeed triggered for the line in question.