Обеспечивает ли 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: да, он находится в стеке.