Вызов конструктора большого массива объектов в стеке - PullRequest
1 голос
/ 04 февраля 2011

Я изменяю некоторый исходный код C ++, и я заметил, что автор действительно старался изо всех сил распределять все в стеке. Скорее всего для выгоды освобождения (есть ли какие-либо преимущества в производительности ??).

Я хочу сохранить ту же последовательность, но мне нужно создать большой массив объектов и что-то вроде:

Object os[1000] = {Object(arg), Object(arg), ....};

не собирается сокращать это. Поиск вокруг выглядит как обходной путь:

vector<Object> os(1000, Object(arg));

Это все еще распределяется в куче, но освобождается как стек (из того, что я читал в других постах). Мне просто интересно, есть ли другие варианты, потому что это похоже на проблему синтаксиса. Возможно, умные люди #define знают.

Ответы [ 4 ]

1 голос
/ 04 февраля 2011

Да, есть и другие варианты.Вы можете использовать что-то вроде alloca.Это даст вам распределение стека и автоматическое освобождение, но не автоматическое построение или уничтожение.Вам нужно будет использовать размещение нового и явного вызова деструкторов.

Да, может быть преимущество в производительности, но вы также просите использовать стек, и этот шаблон не является безопасным для исключения, как vector решение будет (то есть, если объект, который вы размещаете, имеет нетривиальный деструктор).

1 голос
/ 04 февраля 2011

Стек не должен использоваться для больших блоков памяти. Вы просто должны заплатить более высокую цену за выделение кучи в обмен на доступ к большему объему памяти. Другим вариантом является объявление массива со статической продолжительностью хранения, но у него есть другие недостатки (не повторный вход, не потокобезопасный). Все это компромисс.

В любом случае, при выделении сложных объектов стоимость вызова 1000 конструкторов будет меньше времени, затрачиваемого в распределителе. Просто используйте std::vector, если у вас нет данных профилировщика, которые показывают проблему с производительностью.

0 голосов
/ 04 февраля 2011

Это должно сработать:

Object os[1000];
os[0] = Object(args);
std::copy(os, os + 999, os + 1);

Это создает массив, инициализирует один объект, затем проходит по циклу, инициализируя каждый элемент последним.

Конечно, вы, вероятно, не должны использовать это. Это кажется плохой идеей, даже если она работает, и даже если Object os[1000] не доставляет вам проблем.

0 голосов
/ 04 февраля 2011

Распределение больших объемов данных в стеке, вообще говоря, плохая идея.Стек в большинстве операционных систем представляет собой пустое место и довольно ограничен в размерах.Выделение большого объема стекового пространства для объектов может быстро занять все доступное стековое пространство, что приведет к segfault или другому исключению, когда что-то пытается выделить еще одну вещь в стеке (например, адрес возврата для вызова функции).

Что касается других опций, у вас есть несколько .. std :: vector, как вы уже заметили, наряду с boost :: array для таких примеров.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...