Как я могу заставить объект построить себя в определенном месте в памяти?

Возможный дубликат:
Создать новый C++ объект по определенному адресу памяти?

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

Теперь мой вопрос заключается в следующем: как только я получил указатель в своем пуле, как мне создать там объект?


person Alex    schedule 15.07.2010    source источник


Ответы (4)


Вы используете новое размещение. Вот так:

new( pointer ) MyClass();
person Peter Ruderman    schedule 15.07.2010
comment
И не забудьте вызвать деструктор, прежде чем освобождать память. - person Mike Seymour; 15.07.2010

Использовать новое место размещения.

std::vector<char> memory(sizeof(Myclass));    
void*             place = &memory[0];          

Myclass* f = new(place) Myclass();

Не используйте метод, определенный в FAQ:

char     memory[sizeof(Myclass)];  // No alignment guarantees on this.

Как отмечено в FAQ, это опасно, так как стандарт не предусматривает выравнивания этой памяти. Использование стандартного вектора дает вам гарантии выравнивания, поскольку раздел данных вектора выделяется динамически, а стандарт предоставляет гарантии выравнивания динамически выделяемой памяти.

От: n2521 (копия у меня на рабочем столе) Раздел: 3.7.3.1

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

Что указывает нам на 3.11

3.11 Мировоззрение [basic.align]
5 Мировоззрения имеют порядок от более слабого к более сильному или более строгому мировоззрению. Более строгие выравнивания имеют большие значения выравнивания. Адрес, который удовлетворяет требованию выравнивания, также удовлетворяет любому более слабому требованию действительного выравнивания.

Не забудьте вручную вызвать деструктор:

f->~Myclass()
person Martin York    schedule 15.07.2010

Размещение нового может помочь.

Какое использование нового места размещения?

person Rob    schedule 15.07.2010

Используйте новое место размещения

char memory[sizeof(Myclass)];    
void* place = memory;          

Myclass* f = new(place) Myclass();   

Запомнить

Вы также несете единоличную ответственность за уничтожение размещенного объекта. Это делается путем явного вызова деструктора:

 f->~Myclass();

ИЗМЕНИТЬ

После прочтения комментария Мартина Йорка и соответствующего раздела Стандарта совершенно очевидно, что вам не следует использовать вышеуказанный метод (используя объекты, помещенные в стек с новым размещением). Используйте std::vector вместо placement new, как предложил Мартин.

person Prasoon Saurav    schedule 15.07.2010
comment
Не используйте стековые/глобальные переменные с новым размещением. Стандарт не дает никаких гарантий относительно выравнивания стековых/глобальных переменных. В результате вы должны использовать динамически выделяемую память (поскольку стандарт предоставляет правообладателям ее выравнивание). Таким образом, самый простой способ сделать это — использовать вектор (поскольку часть данных вектора выделяется динамически). - person Martin York; 15.07.2010
comment
@Martin: Спасибо, я этого не знал. :) - person Prasoon Saurav; 15.07.2010