【发布时间】:2014-07-27 09:06:46
【问题描述】:
编译器如何在编译时确定下面数组的大小?
int n;
scanf("%d",&n);
int a[n];
它与动态分配有何不同(除了动态数组在堆中分配内存)。
如果可能,请根据激活堆栈内存映像解释这个数组是如何分配内存的。
【问题讨论】:
标签: c
编译器如何在编译时确定下面数组的大小?
int n;
scanf("%d",&n);
int a[n];
它与动态分配有何不同(除了动态数组在堆中分配内存)。
如果可能,请根据激活堆栈内存映像解释这个数组是如何分配内存的。
【问题讨论】:
标签: c
数组的大小不是在编译时确定的;它是在运行时确定的。在分配数组时,n 具有已知值。在程序堆栈上分配自动变量的典型实现中,堆栈指针将被调整以为那么多整数腾出空间。它成为堆栈帧的一部分,并在超出范围时自动回收。
此代码在 C90 中无效; C90 要求在块的开头声明所有变量,因此不允许混合声明和这样的代码。 C99 中引入了可变长度数组以及混合代码和声明。
【讨论】:
sizeof 运算符为非可变长度数组提供了整个数组的大小,这让我认为这仅适用于可变长度数组。
sizeof 是变长数组的特殊用途。
在 C 中,分配类型的正确名称是自动。在计算术语中,术语 stack 有时用作同义词。
a 的存储从定义点 int a[n]; 直到封闭范围的末尾(即当前函数的末尾或更早)都有效。
它与int a[50]; 相同,只是可以分配与50 不同数量的整数。
使用自动数组(有或没有运行时大小)的一个缺点是没有可移植的方法来防止堆栈溢出。 (实际上,自动变量的堆栈溢出是 C 标准根本没有解决的问题,但在实践中却是一个真正的问题。
如果您要使用动态分配(即malloc 和朋友),那么它会通过返回NULL 让您知道内存是否不足,而堆栈溢出是令人讨厌的。
【讨论】:
malloc 也可能不会让您知道是否没有足够的可用内存。 Linux 的惰性分配器可能会报告成功,然后在您尝试实际访问您应该分配的内存时终止您的程序。