我对运行时或编译时是否进行自动内存分配感到困惑

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了我对运行时或编译时是否进行自动内存分配感到困惑相关的知识,希望对你有一定的参考价值。

我知道内存在编译时被分配给像int a;这样的自动变量并且存储在堆栈中但是在变量数组的情况下,其输入来自用户,例如

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

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

答案

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

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

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

在VLA的情况下,在编译时创建指令“移动堆栈指针n步”,但是在运行时设置变量n,然后相应地移动堆栈指针以分配存储器。

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

例子可以找到here

以上是关于我对运行时或编译时是否进行自动内存分配感到困惑的主要内容,如果未能解决你的问题,请参考以下文章

sizeof 是在编译时还是运行时评估?

我对一些反射代码感到困惑,并寻找洞察力

我对 C 上的 malloc() 和 calloc() 感到非常困惑

我对多态性和类对象感到困惑[重复]

堆栈指针的内存分配

对leal感到困惑。它是不是也访问内存地址的内容?