TGViewer
C/C++ | Вопросы собесов C/C++ | Вопросы собесов @easy_c_plus · 4.19K subscribers
Post #2553 285
🤔 Что такое placement new?

placement new – это специальная форма оператора new, которая размещает объект в уже выделенной памяти вместо того, чтобы выделять её заново.
placement new
НЕ выделяет память (мы сами передаём адрес).
Просто вызывает конструктор в указанном месте.
void* ptr = malloc(sizeof(int));   // Выделяем память вручную
int* num = new(ptr) int(42); // Размещаем объект в этой памяти


Синтаксис placement new
new (адрес) Type(аргументы конструктора);


адрес – указатель на уже выделенную память.
Type(аргументы конструктора) – объект создаётся в этом месте.
#include <iostream>

int main() {
char buffer[sizeof(int)]; // Буфер памяти (размер как у int)

int* p = new (buffer) int(123); // Размещаем int в этом буфере

std::cout << "Значение: " << *p << std::endl; // 123
}


🚩Когда используется `placement new`?

🟠Оптимизация выделения памяти
Например, если у нас часто создаются и удаляются объекты, но память уже есть. Не нужно каждый раз вызывать new и delete.

🟠Размещение объектов в особых областях памяти
Например, на стеке (char buffer[100]), в shared memory, или в выделенной заранее области (malloc).

🟠Создание объекта в заранее выделенном массиве
Стандартный std::vector использует placement new внутри себя!

🟠Кастомные аллокаторы (`std::allocator`)
Например, в играх и в embedded-разработке, где управление памятью критично.

🚩`placement new` и классы

Если объект – это класс, placement new вызывает его конструктор в выделенной памяти.
#include <iostream>
#include <cstdlib> // Для malloc/free

class MyClass {
public:
int x;
MyClass(int val) : x(val) { std::cout << "Конструктор!\n"; }
~MyClass() { std::cout << "Деструктор!\n"; }
};

int main() {
void* buffer = malloc(sizeof(MyClass)); // Выделяем сырую память
MyClass* obj = new (buffer) MyClass(42); // Размещаем объект

std::cout << "Значение: " << obj->x << std::endl;

obj->~MyClass(); // Ручной вызов деструктора!
free(buffer); // Освобождаем память
}


Вывод
Конструктор!
Значение: 42
Деструктор!


🚩Ошибки при `placement new`

Забыл вызвать деструктор
MyClass* obj = new (buffer) MyClass(10);
// delete obj; // НЕЛЬЗЯ! Обычный `delete` не работает
free(buffer); // Память утекла! Деструктор не вызвался


Нужно вызвать вручную
obj->~MyClass();
free(buffer);


placement new в одном буфере несколько раз (без очистки)*
void* buffer = malloc(sizeof(MyClass));
MyClass* obj1 = new (buffer) MyClass(1);
MyClass* obj2 = new (buffer) MyClass(2); // Перезапишет obj1!


Нужно сначала вызвать деструктор
obj1->~MyClass();
MyClass* obj2 = new (buffer) MyClass(2);


Освободил память перед вызовом деструктора
free(buffer);  // Память освободили
obj->~MyClass(); // ОШИБКА! Память уже не существует


Правильный порядок
obj->~MyClass();
free(buffer);


Ставь 👍 и забирай 📚 Базу знаний
More from @easy_c_plus
  1. Oct 9, 2026🤔 Строгая гарантия безопасности Гарантии безопасности исключений в C++ делятся на три уро…
  2. Oct 8, 2026🤔 Выбрасывание исключения из конструктора — это нормально? Да, выбрасывание исключения из…
  3. Oct 8, 2026🤔 Какое преимущество у list перед vector? List обеспечивает быстрые вставки и удаления за…
  4. Oct 7, 2026🤔 Как работает priority_queue? priority_queue управляет элементами на основе их приоритет…
  5. Oct 7, 2026🔥 Скрытые вакансии с удаленной работой для C/C++ разработчика, которые нигде больше не пу…
  6. Oct 6, 2026🤔 Какое присваивание разрешает unique_ptr? unique_ptr поддерживает только перемещение (mo…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →