2016-09-17 14 views
16

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

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

ответ

11

я не мог найти более ясный ответ в стандарте, но [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 был введен в C++ 11. Зачем? Например, в дополнение к std::vector в некотором смысле, например, использование в функциях constexpr, где динамическое распределение не допускается.

+2

+1 Другими словами, вы получаете те же гарантии, что и 'template struct array {T elems [N]; }; 'w.r.t. layout ('elems' фактически не существует). – GManNickG

+4

@towi: Обратите внимание, что C++ на самом деле не имеет понятия стека или кучи. Обычно мы получаем то, что вы имеете в виду, но вы спросили «по стандарту C++». Вы получаете те же гарантии, что и приведенный выше пример; как это распределяется, зависит от вашей реализации. (В теории я мог бы написать немой компилятор, который вообще не использует стек, и динамически выделяет все.) – GManNickG

+0

@GManNickG Знаешь, я полностью пропустил это! «нет понятия стека и кучи», на самом деле? Также нет «динамически» или «статически» выделено? Возможно, вы правы, быстрый поиск в Std согласен с этим. Я предполагаю, что определение, если 'new' и spec' ', описывающее динамическое распределение, специально заставило меня пропустить отсутствие статической спецификации распределения. Учитывая ваш немой компилятор, мне интересно, можно ли вообще сделать все на стеке. Нет, вероятно, нет, как я могу поддержать «новый»? Но это другой вопрос. – towi

11

В 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++, но нет никакой необходимости, так никто надоедает.

TL; DR: да, это на стеке.

+1

Можете ли вы указать мне на эту интересную реализацию без стекол? Звучит ужасно интересно. (Эти вещи никогда не TL, DR ...) – towi

+0

@towi извините, я знаю, что это существует, вот и все. – Yakk

+3

@towi [мейнфреймы IBM, по-видимому.] (Http://stackoverflow.com/questions/10900885/are-there-stackless-or-heapless-implementation-of-c) Немного подробнее в комментариях к ответу Джерри Коффина там. – hvd