如何在循环中声明分配的数组?
How are allocated arrays declared in a loop?
我对这个功能感到困惑。
int i;
for(i = 1; i<10; i++){
int arr[i];
printf("%d\n",sizeof(arr));
}
return 0;
space 如何在有界(通过 ESP)堆栈内存中增长?
有什么编译技巧吗?
编辑解释:
堆栈不应该是这样的吗?
0 ---> val of i uninitialized
-4 ---> arr[0] uninitialized
在第一个循环之后
0 ---> val of i uninitialized
-4 ---> arr[1] uninitialized
-8 ---> arr[0] uninitialized
我很想说:ESP 是否在循环的每次迭代下方移动?
How can the space grow in a bounded size stack memory?
您指的是 char arr
的 space - 它的 space 没有增长。它是 for
循环范围内的局部变量。所以每次循环都有一个新的 i
它是一个全新的 char arr
.
Is there a sort of compilation trick?
是的,有点。它使用 VLA (https://en.wikipedia.org/wiki/Variable-length_array)
Godbolt 对于检查这样的事情非常有用:
如您所见,确实针对相关行触发了 -Wvla
警告。
在每个循环中,都会为数组分配堆栈,然后释放。
有点不同的例子
#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);
}
编译后的代码
.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
第 15、19 和 20 行分配 space
第 28 行为数组
解除分配 space
我对这个功能感到困惑。
int i;
for(i = 1; i<10; i++){
int arr[i];
printf("%d\n",sizeof(arr));
}
return 0;
space 如何在有界(通过 ESP)堆栈内存中增长? 有什么编译技巧吗?
编辑解释: 堆栈不应该是这样的吗?
0 ---> val of i uninitialized
-4 ---> arr[0] uninitialized
在第一个循环之后
0 ---> val of i uninitialized
-4 ---> arr[1] uninitialized
-8 ---> arr[0] uninitialized
我很想说:ESP 是否在循环的每次迭代下方移动?
How can the space grow in a bounded size stack memory?
您指的是 char arr
的 space - 它的 space 没有增长。它是 for
循环范围内的局部变量。所以每次循环都有一个新的 i
它是一个全新的 char arr
.
Is there a sort of compilation trick?
是的,有点。它使用 VLA (https://en.wikipedia.org/wiki/Variable-length_array)
Godbolt 对于检查这样的事情非常有用:
如您所见,确实针对相关行触发了 -Wvla
警告。
在每个循环中,都会为数组分配堆栈,然后释放。
有点不同的例子
#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);
}
编译后的代码
.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
第 15、19 和 20 行分配 space 第 28 行为数组
解除分配 space