我有点困惑,自动内存分配是发生在 运行 时间还是编译时间
I'm little bit confused that whether automatic memory allocation takes place during run time or compile time
我知道内存是在编译时分配给像int a;
这样的自动变量的,并存储在堆栈中,但是如果是从用户那里获取输入的变量数组,例如
#include<stdio.h>
main()
{
int n;
printf("enter the size of array");
scanf("%d",&n);
int a[n];
.......
}
内存在 运行 时分配。所以我的问题是,自动分配是否取决于具体情况。谢谢
在您的示例中,不清楚 "a" 的定义位置。因此,我将通过对此做出假设来尝试回答这个问题。
- 如果数组被声明为全局数组,它驻留在 bss 段中,并且在将段加载到内存中时分配内存。
- 如果数组在栈上,并且数组的大小在编译时已知,则栈指针被移动到为数组分配space。反汇编代码就可以看到这个
- 如果数组在堆栈上,但 space 是根据函数的参数分配的,则您有一个 VLA(可变长度数组)。这些通常由编译器转换为 "alloca" 调用。在这种情况下,堆栈指针只是移动到堆栈上分配的 "n" 字节。
- 如果数组在堆上,则分配由正在使用的堆分配器执行。
处理自动分配的代码是在编译时创建的。实际分配发生在 运行 时间内。您将拥有诸如 "push variable on stack" 或 "put variable in register" 之类的机器代码,但在程序执行之前,这些代码当然什么都不做。所有堆栈分配都在 运行 时间内完成。它们可能具有也可能不具有确定性。
在VLA的情况下,指令"move stack pointer n steps"是在编译时创建的,但是变量n
是在运行时设置的,然后堆栈指针被移动相应地,分配内存。
在编译时发生的唯一一种分配是分配具有静态存储持续时间的对象 - 即文件范围变量和 static
变量的分配。在大多数系统上通常名为 .data
和 .bss
的数据段中保留了这些空间。
可以找到示例 here。
我知道内存是在编译时分配给像int a;
这样的自动变量的,并存储在堆栈中,但是如果是从用户那里获取输入的变量数组,例如
#include<stdio.h>
main()
{
int n;
printf("enter the size of array");
scanf("%d",&n);
int a[n];
.......
}
内存在 运行 时分配。所以我的问题是,自动分配是否取决于具体情况。谢谢
在您的示例中,不清楚 "a" 的定义位置。因此,我将通过对此做出假设来尝试回答这个问题。
- 如果数组被声明为全局数组,它驻留在 bss 段中,并且在将段加载到内存中时分配内存。
- 如果数组在栈上,并且数组的大小在编译时已知,则栈指针被移动到为数组分配space。反汇编代码就可以看到这个
- 如果数组在堆栈上,但 space 是根据函数的参数分配的,则您有一个 VLA(可变长度数组)。这些通常由编译器转换为 "alloca" 调用。在这种情况下,堆栈指针只是移动到堆栈上分配的 "n" 字节。
- 如果数组在堆上,则分配由正在使用的堆分配器执行。
处理自动分配的代码是在编译时创建的。实际分配发生在 运行 时间内。您将拥有诸如 "push variable on stack" 或 "put variable in register" 之类的机器代码,但在程序执行之前,这些代码当然什么都不做。所有堆栈分配都在 运行 时间内完成。它们可能具有也可能不具有确定性。
在VLA的情况下,指令"move stack pointer n steps"是在编译时创建的,但是变量n
是在运行时设置的,然后堆栈指针被移动相应地,分配内存。
在编译时发生的唯一一种分配是分配具有静态存储持续时间的对象 - 即文件范围变量和 static
变量的分配。在大多数系统上通常名为 .data
和 .bss
的数据段中保留了这些空间。
可以找到示例 here。