#c #new-operator #delete-operator #placement-new
Вопрос:
Здравствуйте, чтобы понять больше placement new
, operator new
, выражение delete
.. и отделить инициализацию от построения, я попробовал этот пример:
int main(){
int* p = static_cast<int*>(operator new[](10 * sizeof(int)));
p = new(p)int[10];
for(int i = 0; i != 10; i)
p[i] = i * 7;
for(int i = 0; i != 10; i)
std::cout << p[i] << ", ";
operator delete[](p);
}
- Я скомпилировал его и запустил, и он отлично работает, и проверил его с помощью Valgrind на наличие утечек памяти, и ничего плохого не сообщается. Так это как отделить инициализацию от распределения?
- В чем я не уверен, так это в том, что я использовал оператор delete для освобождения памяти динамического массива, но не уничтожил его (удаление размещения отсутствует). Так есть ли что-то плохое в моем коде?
Ответ №1:
Как вы заметили, нет placement delete
. При использовании placement new
вам придется вызывать деструкторы вручную , например:
void* mem = operator new[](10 * sizeof(T));
T* p = new(mem) T[10];
...
for(int i = 0; i < 10; i)
p[i].~T();
operator delete[](mem);
Где T
указан желаемый тип элемента.
Вызов деструкторов не очень важен для типов модулей, например int
, но это важно для типов, отличных от модулей , например std::string
, и т. Д., Чтобы избежать утечек.
Комментарии:
1. Вы должны быть осторожны с подобным кодом. Некоторые реализации размещения
new []
добавляют префикс «количество массивов» к массиву вновь построенных объектов, что исключает вычисление пространства для указанного массива. Вы также предполагаете, что возвращаемое значениеnew(p) T[10]
равноp
. Опять же, это не всегда верно. Из-за этого лучше вызывать форму размещения без массиваnew
в цикле. Тогда (при условии, что вы все сделаете правильно) ничего не может пойти не так.