50

std::array<int,10>(没有我自己使用)是否new保证被分配在堆栈中而不是 C++ 标准的堆中?

说清楚,我不是说new std::array<int, 10>。我主要想知道,是否允许new在其实现中使用标准库。

4

2 回答 2

41

TL;DR:是的,它在堆栈上。


更长的故事:

C++ 没有堆栈或堆的概念。这些是实现细节,并且至少有一个平台不使用传统的堆栈(而是使用堆分配的链表)。

它具有自动存储和免费存储。 new访问免费存储,并且“堆栈上”的变量进入自动存储。

在实践中,为了在空闲存储上分配东西,您必须冒内存不足异常的风险。所以一般规则是保证不扔的东西必须使用自动存储。 array做出这个保证(除了里面的东西可以抛出,自然)。它也是普通旧数据的聚合,实际上被迫看起来像:

template<class T,std::size_t N>
struct array {
  T __no_fixed_name__[N];
  // non-constructor/destructor methods omitted as they are noise at this point
};

从理论上讲,它可以由编译器通过不是真正的 C++ 的魔法来实现,但没有必要这样做,所以没有人打扰。

所以总而言之:是的,std::array在堆栈上。

于 2016-09-17T17:12:35.783 回答
30

我在标准中找不到更明确的答案,但是[array.overview]/2

数组是一个聚合( ) ,最多可以使用其类型可转换为 的元素[dcl.init.aggr]进行列表初始化。NT

并且[dcl.init.aggr]/1

聚合是一个数组或一个类子句[class]

  • 没有用户提供的、显式的或继承的构造函数[class.ctor]),

...

那大约涵盖了它。聚合不可能动态分配内存(或者可能在构建过程中自己做任何事情)。只有一个隐式声明的琐碎构造函数。

当然,如果你new std::array<...>,你会在“堆”上得到一个数组。


有些人可能对我们在cppreference上得到的东西更满意:

std::array是一个封装固定大小数组的容器。

此容器是一种聚合类型,其语义与将 C 样式数组T[N]作为其唯一非静态数据成员的结构相同。


第三,std::array在 C++11 中引入。为什么?例如,std::vector在某些方面进行补充,例如在constexpr不允许动态分配的函数中使用。

于 2016-09-17T15:08:52.303 回答