placement new 是 c++ 中不分配内存、仅在指定地址调用构造函数的 new 表达式;需手动调用析构函数,不可用 delete 销毁,常用于内存池、STL 容器及嵌入式系统。

placement new 是 C++ 中一种特殊的 new 表达式,它不分配内存,而是直接在你已提供的、预先分配好的内存地址上构造对象。
核心作用:只调用构造函数,不申请堆内存
普通 new 会做两件事:调用 operator new 分配内存,再在该内存上调用构造函数。而 placement new 跳过第一步,只执行第二步——在你指定的地址上调用构造函数。
典型写法:
char buffer[sizeof(MyClass)];<br>MyClass* obj = new (buffer) MyClass(42); // 在 buffer 起始地址构造对象
必须手动管理生命周期
因为 placement new 没有分配内存,所以不能用 delete 销毁对象——那会尝试释放未由 new 分配的内存,导致未定义行为。
立即学习“C++免费学习笔记(深入)”;
- 要销毁对象,需显式调用析构函数:
obj->~MyClass(); - 如果原始内存是用
malloc或operator new分配的,之后还需手动free或operator delete - 若内存来自栈数组(如上面的
buffer),则无需释放,但析构仍要手动调用
常见使用场景
- 内存池或自定义分配器:复用一块大内存,反复构造/析构不同对象
- 嵌入式或实时系统:避免动态分配,确保确定性行为
- STL 容器实现:如
std::vector内部在已分配的原始内存上调用 placement new 构造元素 - 对象序列化/反序列化:把数据按布局直接“复活”为对象
注意 operator new 的重载形式
placement new 本质是 operator new 的一个重载版本,签名为:
void* operator new(std::size_t, void* p) noexcept { return p; }
这个版本不分配内存,只是原样返回传入的指针 p。编译器识别 new (ptr) T(...) 语法后,就会调用它。
你也可以定义自己的带额外参数的 placement new(比如带对齐、日志等),只要提供对应 operator new 声明即可。
基本上就这些。它不复杂,但容易忽略手动析构和内存归属问题。