Обеспечивает ли std:: array <> выделение только в стеке?

Является ли std::array<int,10> (без меня с помощью new) гарантированно выделяемым в стеке, а не кучей по стандарту С++?

Чтобы быть ясным, я не имею в виду new std::array<int, 10>. Я в основном задаюсь вопросом, может ли стандартная библиотека использовать new внутри своей реализации.

Ответы

Ответ 1

Я не смог найти более явный ответ в стандарте, но [array.overview]/2:

Массив - это агрегат ([dcl.init.aggr]), который можно инициализировать списком с помощью N элементов, типы которых можно конвертировать в T.

И [dcl.init.aggr]/1:

Агрегат - это массив или класс (раздел [class]) с

  • без пользовательских, явных или унаследованных конструкторов ([class.ctor]),

...

Это обложки. Ни в коем случае совокупность не может распределять память динамически (или, возможно, делать что-либо вообще самостоятельно во время строительства). Там только неявно объявленный тривиальный конструктор.

Конечно, если вы new std::array<...>, вы получите массив на "куче".


Некоторые могут быть более удовлетворены тем, что мы можем получить на cppreference:

std::array - это контейнер, который инкапсулирует массивы фиксированного размера.

Этот контейнер представляет собой совокупный тип с той же семантикой, что и структура, содержащая массив C-style T[N] как единственный нестатический элемент данных.


В-третьих, std::array был введен в С++ 11. Зачем? Например, в дополнение к std::vector в некотором роде, например, использование в функциях constexpr, где динамическое распределение не разрешено.

Ответ 2

У С++ нет понятия стека или кучи. Это детали реализации, и есть хотя бы одна платформа, которая не использует традиционный стек (но скорее связанный список распределений кучи для него).

У него есть автоматическое хранилище и бесплатный магазин. 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
};

Теоретически это может быть реализовано компилятором с помощью магии, которая не является реальным С++, но в этом нет необходимости, поэтому никто не беспокоится.

TL; DR: да, он находится в стеке.