在运行时确定数组大小时,是从堆栈还是堆分配?

时间:2016-05-02 08:59:34

标签: c arrays variable-length-array

在下面的代码中,是从堆栈还是堆分配arr[n]

我很困惑,因为一般来说,数组大小是在编译时确定的。以下代码如何工作?

#include<stdio.h>
int main(){
    int n;
    scanf("%d",&n);
    int arr[n];
    for(int arr_i = 0; arr_i < n; arr_i++){
       scanf("%d",&arr[arr_i]);
    }
    for(int arr_i = (n-1); arr_i >= 0; arr_i--){
       printf("%d ",arr[arr_i]);
    }
}

6 个答案:

答案 0 :(得分:3)

那是可变长度数组。它在C99标准中是必需的,对C11符合编译器来说是可选的 - 正如其他人在评论中所说,它在C ++中不支持任何版本。

它声明一个具有自动存储持续时间的数组,通常使用堆栈存储实现。但请记住,即使所有编译器都使用堆栈和堆的概念,它只是一个实现细节。

答案 1 :(得分:2)

在您的情况下,您正在使用的内容称为variable length array。此功能已在C99中引入,但在C11中再次成为可选项。

实际上,C标准没有对VLA的分配施加任何规范。这个决定由编译器决定。

The widely-used gcc allocates VLAs on stack memory

答案 2 :(得分:2)

在C99中添加了可变长度阵列。在C11中,它们已被缩减为可选项。

C标准没有指定存储变量的位置,因此由编译器制造商决定。

gcc stores VLA:s on the stack

答案 3 :(得分:1)

在具有C99的可变长度数组(VLA)出现之前,大小必须是整数常量,其中包括由常量整数值形成表达式的可能性。

话虽如此,为a[n]分配的内存通常是静态的,就像gcc一样,但是没有关于如何为VLA分配内存的正式规范

有趣的链接

  1. Which Compiler Should I trust?

  2. GNU-GCC note on VLA.

  3. Diary of a graphics programmer(参见缺少的内容)

  4. Enabling VLAs in MS Visual C++

答案 4 :(得分:0)

GCC(GNU Compiler Collection)编译器为C添加了许多通常被忽视的扩展。这些添加的扩展可以帮助我们简化C应用程序的开发。其中一个扩展是添加了可变长度数组和零长度数组。

  

在下面的代码中,是从堆栈或堆中分配arr [n]。

GCC允许使用非常量表达式声明数组。这在ISO C99中是可能的,但在C89中则不行。 GNU C编译器为堆栈上的可变长度数组分配内存。与C中的所有对象一样,VLA限制为SIZE_MAX字节。

来源 - https://en.wikipedia.org/wiki/Variable-length_array#cite_note-7

答案 5 :(得分:0)

当你声明数组int arr [n];它将具有自动范围,即,它将仅在该功能内具有范围。并且这个内存将从堆栈中分配出来。只有那些使用malloc,calloc等分配的变量才会进入堆。有关详细信息,请查看memory layout of c program&amp; automatic variable