动态大小的数组是在哪里创建的?(堆栈还是堆)

3
例如,我有一个基于用户输入的动态大小的数组:
int n;
cin >> n;
int items[n];

这个数组是分配在堆栈上吗?还是像我下面所写的那样在堆上?

int n, *items;
cin >> n;
items = new int[n];
...
delete [] items;

编辑:我理解第二段代码的作用。我想知道第一段代码是否能用更少的行数实现相同的功能。


相关:https://dev59.com/BnM_5IYBdhLWcg3w6X1e#1169916 - sehe
3个回答

7

你的第一个示例根本没有使用动态数组 - 它使用的是在栈上分配的变长数组(通常在幕后相当于alloca调用,除了sizeof运算符之外),这是C99的一个特性,而不是C ++。

当然,你的第二个数组是通过new在堆上分配的。


7
请注意,标准C++不支持可变长度数组,因此第一个代码片段在C99(没有iostream)和C++(没有VLAs)中都会出现语法错误。尽管如此,一些编译器作为扩展支持C++中的VLAs。 - In silico
@Insilico 正确,但许多 C++ 编译器支持 C99 特性作为扩展(至少 GCC、Clang,可能 MSVC 也是)。 - Richard J. Ross III
1
@Insilico 我会无警告编译。已使用g++进行测试,没有任何构建参数。 - kravemir
1
它能够工作是因为可变长度数组(这是第一个代码片段所需的)被GCC作为扩展支持。它在标准C++中不受支持。 - In silico
@Insilico 是的,我现在已经全部阅读完了。但是为什么它可以编译而没有任何警告呢? - kravemir
2
@Miro:使用扩展时,编译器不需要发出警告。GCC的编译器编写者选择在这种情况下不发出警告(尽管如果您启用了所有警告,则可能会发出警告)。 - In silico

3
您使用new来分配内存,因此您的数组存储在堆中。

我在询问动态大小数组背后的原理,而不是第二段代码的含义 :) - kravemir
2
是的,在这种情况下,堆是作为动态大小数组的后备存储器。您还想知道什么? - In silico
如果您创建一个没有使用“new”或动态内存分配函数且大小是常量的数组,则它会存储在堆栈中。如果您为数组分配内存(大小也可能是非常量表达式),则它位于堆中。 - nabroyan

-1

你的第一个代码块将无法编译,如果没有使用new或malloc/calloc/realloc进行内存分配,就不能分配动态大小的数组。

为了实现你想要的功能,你需要像第二个代码块一样,在堆上进行分配。

动态 = 堆。非动态 = 栈。

始终记得释放你的内存!


1
@Miro:它能够工作是因为可变长度数组(这是第一个代码片段所需的)被作为扩展由GCC支持。它在标准C++中不受支持。 - In silico
1
请理解问题的第一部分中显示的VLA是C99扩展,被大多数现代编译器支持。 - Richard J. Ross III

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接