std :: array <>是否只保证堆栈的分配?

tow*_*owi 30 c++ arrays stack static-allocation dynamic-allocation

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

要清楚,我不是故意的new std::array<int, 10>.我主要想知道,如果允许标准库new在其实现中使用.

Yak*_*ont 21

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
};
Run Code Online (Sandbox Code Playgroud)

理论上它可以由编译器通过不是实际C++的魔法来实现,但是没有必要这样做,所以没有人会烦恼.

所以总结:是的,std::array是在堆栈上.

  • 你能指出那个有趣的无堆栈实现吗?听起来非常有趣。(这些东西从来都不是 TL;DR...) (3认同)
  • @towi [显然是IBM大型机.](http://stackoverflow.com/questions/10900885/are-there-stackless-or-heapless-implementation-of-c)关于Jerry Coffin在那里的回答的评论中有更多细节. (3认同)
  • 我曾经使用过一个 C 系统,其中自动变量没有存储在堆栈中。相反,使用了静态数据区中的空间;它默认允许每个函数变量的 3 个副本来处理重入,但如果您输入超过 3 次,您将被吐司 (3认同)
  • 我想指出 `std::array` 模板签名有两个参数。第一个是类型,第二个是元素数量。需要注意的是,分配器没有第三个模板参数。 (2认同)
  • 在我看来,知道“std::array”驻留在堆栈上很重要,因为这样您就可以避免在堆栈上声明一个大的“std::array”并导致程序崩溃。 (2认同)

Log*_*uff 17

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

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

而且[dcl.init.aggr]/1:

聚集体是一个数组或一个类(条款[class])

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

...

那就是它.聚合无法动态分配内存(或者在构造过程中可能自己做任何事情).只有一个隐式声明的琐碎构造函数.

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


有些人可能会对我们在cppreference上获得的内容感到满意:

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

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


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

  • @towi:请注意,C++并不真正具有堆栈或堆的概念.通常我们得到你的意思,但你问"按照c ++标准".你得到的保证与我上面给出的例子相同; 如何分配这取决于您的实施.(理论上我可以编写一个根本不使用堆栈的哑编译器,并动态分配所有内容.) (6认同)
  • +1换句话说,你得到与`template <class N,size_t N> struct array {T elems [N]; ``wrt layout(`elems`实际上并不存在). (3认同)