C I';我有点困惑,自动内存分配是在运行时还是编译时进行的

C I';我有点困惑,自动内存分配是在运行时还是编译时进行的,c,memory-management,dynamic-memory-allocation,static-memory-allocation,C,Memory Management,Dynamic Memory Allocation,Static Memory Allocation,我知道内存是在编译时分配给自动变量的,比如inta和存储在堆栈中,但对于从用户获取输入的变量数组,例如 #include<stdio.h> main() { int n; printf("enter the size of array"); scanf("%d",&n); int a[n]; ....... } #包括 main() { int n; printf(“输入数组的大小”); scanf(“%d”和“&n”); int a[n]; ....... }

我知道内存是在编译时分配给自动变量的,比如
inta和存储在堆栈中,但对于从用户获取输入的变量数组,例如

#include<stdio.h>
main()
{
 int n;
 printf("enter the size of array");
 scanf("%d",&n);
 int a[n];
 .......
}
#包括
main()
{
int n;
printf(“输入数组的大小”);
scanf(“%d”和“&n”);
int a[n];
.......
}

内存在运行时分配。所以我的问题是,自动分配是否取决于具体情况。谢谢在您的示例中,不清楚“a”的定义在哪里。因此,我将尝试通过假设来回答这个问题

  • 如果数组声明为全局数组,则它驻留在bss段中,并在将段加载到内存时分配内存
  • 如果数组位于堆栈上,并且在编译时知道数组的大小,则会移动堆栈指针为数组分配空间。如果反汇编代码,您可以看到这一点
  • 如果数组位于堆栈上,但空间是基于函数的参数分配的,则您有一个VLA(可变长度数组)。这些调用通常由编译器转换为“alloca”调用。在这种情况下,堆栈指针只是移动到堆栈上分配的“n”字节
  • 如果数组位于堆上,则分配由正在使用的堆分配器执行

  • 在您的示例中,“a”的定义不清楚。因此,我将尝试通过假设来回答这个问题

  • 如果数组声明为全局数组,则它驻留在bss段中,并在将段加载到内存时分配内存
  • 如果数组位于堆栈上,并且在编译时知道数组的大小,则会移动堆栈指针为数组分配空间。如果反汇编代码,您可以看到这一点
  • 如果数组位于堆栈上,但空间是基于函数的参数分配的,则您有一个VLA(可变长度数组)。这些调用通常由编译器转换为“alloca”调用。在这种情况下,堆栈指针只是移动到堆栈上分配的“n”字节
  • 如果数组位于堆上,则分配由正在使用的堆分配器执行
  • 处理自动分配的代码在编译时创建。实际分配在运行时进行。您将拥有诸如“堆栈上的push变量”或“寄存器中的put变量”之类的机器代码,但在程序执行之前,这些代码当然不会执行任何操作。所有堆栈分配都在运行时完成。它们可能具有也可能不具有确定性

    对于VLA,在编译时创建指令“move stack pointer n steps”,但在运行时设置变量
    n
    ,然后相应地移动堆栈指针以分配内存

    在编译时发生的唯一一种分配是具有静态存储持续时间的对象的分配—这意味着文件范围变量和
    静态变量的分配。在大多数系统上,通常命名为
    .data
    .bss
    的数据段中都预留了空间

    可以找到示例。

    处理自动分配的代码是在编译时创建的。实际分配在运行时进行。您将拥有诸如“堆栈上的push变量”或“寄存器中的put变量”之类的机器代码,但在程序执行之前,这些代码当然不会执行任何操作。所有堆栈分配都在运行时完成。它们可能具有也可能不具有确定性

    对于VLA,在编译时创建指令“move stack pointer n steps”,但在运行时设置变量
    n
    ,然后相应地移动堆栈指针以分配内存

    在编译时发生的唯一一种分配是具有静态存储持续时间的对象的分配—这意味着文件范围变量和
    静态变量的分配。在大多数系统上,通常命名为
    .data
    .bss
    的数据段中都预留了空间


    可以找到一些例子。

    似乎你可以自己解释。如果编译时不知道
    n
    的值,但将在运行时根据用户输入确定,那么在编译时不可能分配内存,对吗?因为编译时不知道
    n
    的值,所以所有内存都是在运行时分配的,并且只在运行时分配。不可能在编译时“分配”任何内容。编译时所能做的就是根据绝对或相对偏移量“绘制”未来内存布局。此内存布局在运行时具体化(分配)。@AnT因此,如果所有分配都发生在运行时,那么静态内存分配也会发生在运行时,因为据说它发生在编译时。@KenWhite这就是我的问题所在,它是否依赖于大小写?@Coderandhacker:“分配”这是一个相当模糊的术语。它可能意味着几件不同的事情。例如,规划未来内存布局是“分配”。从环境请求实际内存块也是“分配”。前者发生在编译时,后者发生在运行时。你的问题触及/混合/混淆了这两个概念,这可能是问题本身的原因。似乎你可以自己解释清楚。如果编译时不知道
    n
    的值,但将在运行时根据用户输入确定,那么在编译时不可能分配内存,对吗?因为编译时不知道
    n
    的值,所以所有内存都是在运行时分配的,并且只在运行时分配。不可能在编译时“分配”任何内容。编译时所能做的就是根据绝对或相对偏移量“绘制”未来内存布局。此内存布局在运行时具体化(分配)。@AnT因此如果所有