我有点困惑于是否在运行时或编译时发生了自动内存分配

时间:2017-12-21 00:28:57

标签: c memory-management dynamic-memory-allocation static-memory-allocation

我知道内存在编译时分配给自动变量,如int a;,并存储在堆栈中,但是如果是一个变量数组,其输入来自用户,例如

#include<stdio.h>
main()
{
 int n;
 printf("enter the size of array");
 scanf("%d",&n);
 int a[n];
 .......
}

在运行时分配内存。所以我的问题是,自动分配是否依赖于案例。致谢

2 个答案:

答案 0 :(得分:1)

在您的示例中,不清楚“a”的定义位置。所以,我会通过对此做出假设来尝试回答这个问题。

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

答案 1 :(得分:1)

处理自动分配的代码是在编译时创建的。实际分配在运行时进行。您将拥有机器代码,例如&#34;在堆栈上推送变量&#34;或者&#34;将变量放入寄存器&#34;,但是这个代码当然在程序执行之前什么都不做。所有堆栈分配都在运行时完成。它们可能具有也可能不具有确定性。

在VLA的情况下,指令&#34;移动堆栈指针n步&#34;在编译时创建,但变量n在运行时设置,然后相应地移动堆栈指针,以分配内存。

在编译时发生的唯一分配是分配具有静态存储持续时间的对象 - 意味着分配文件范围变量和static变量。在大多数系统中,通常将这些数据段保留为.data.bss

可以找到示例here