C 编译时数组的静态内存分配

C 编译时数组的静态内存分配,c,C,编译器如何在编译时确定bellow数组的大小 int n; scanf("%d",&n); int a[n]; 它与动态分配有什么不同(除了内存是在动态数组的堆中分配的) 如果可能,请根据激活堆栈内存映像解释如何分配此数组的内存。在编译时不确定数组的大小;它是在运行时确定的。在分配数组时,n具有已知值。在程序堆栈上分配自动变量的典型实现中,堆栈指针将被调整,以便为如此多的int腾出空间。它将成为堆栈框架的一部分,并在超出范围时自动回收 此代码在C90中无效;C90要求在块的开头声明所有

编译器如何在编译时确定bellow数组的大小

int n;
scanf("%d",&n);
int a[n];
它与动态分配有什么不同(除了内存是在动态数组的堆中分配的)


如果可能,请根据激活堆栈内存映像解释如何分配此数组的内存。

在编译时不确定数组的大小;它是在运行时确定的。在分配数组时,
n
具有已知值。在程序堆栈上分配自动变量的典型实现中,堆栈指针将被调整,以便为如此多的int腾出空间。它将成为堆栈框架的一部分,并在超出范围时自动回收


此代码在C90中无效;C90要求在块的开头声明所有变量,因此不允许这样混合声明和代码。C99中引入了可变长度数组、混合代码和声明。

在C中,分配类型的正确名称是自动的。在计算行话中,术语堆栈有时是同义词

a
的存储从定义角度来看是有效的
int a[n]直到封闭范围结束(即当前函数结束或更早)

它与
inta[50]完全相同,但可分配不同于
50
的整数

使用自动数组(有或没有运行时大小)的一个缺点是没有可移植的方法来防止堆栈溢出。(实际上,来自自动变量的堆栈溢出是C标准根本没有解决的问题,但实际上这是一个真正的问题)


如果您要使用动态分配(即
malloc
和friends),那么它将通过返回
NULL
,让您知道内存是否不足,而堆栈溢出非常严重。

实际上,
malloc
也可能不会让您知道内存是否不足。Linux的惰性分配器可能会报告成功,然后在稍后您尝试实际访问假定分配的内存时终止您的程序。这是真的。但是它仍然比堆栈溢出更整洁(并且在运行到堆栈溢出之前通常有更多的可用空间)。请原谅,
sizeof
操作符为非可变长度数组提供了整个数组的大小,让我觉得这只适用于可变长度数组。@ThoAppelsin:
sizeof
是专用于可变长度数组的。