std::destroy_at仅调用析构函数而不释放内存,适用于placement new、内存池等需析构与内存释放解耦的场景;delete则先析构再归还内存,混用会导致崩溃或UB。
std::destroy_at 用来做什么,和 delete 有什么区别
std::destroy_at 只调用对象的析构函数,不释放内存。它适用于 placement new 构造的对象、内存池中预分配的缓冲区、或 std::vector 等容器内部手动管理对象生命周期的场景。而 delete 会先调用析构函数,再调用 operator delete 归还内存——这对内存池来说是错的,因为内存本就不该交还给系统。
常见错误现象:std::destroy_at(&obj) 后又 delete &obj,导致重复析构或非法内存操作;或者在栈对象上误用 std::destroy_at,触发未定义行为(UB)。
- 只能用于已构造成功的对象(即其构造函数已完整执行)
- 参数必须是指向对象的指针,不能是
nullptr(否则 UB) - 对 trivially destructible 类型(如
int、struct无析构函数),std::destroy_at是空操作,但语义上仍合法
在内存池中手动销毁对象的典型流程
内存池通常用一块大内存块 + 自定义分配器管理对象。对象用 placement new 构造后,销毁阶段必须跳过 delete,只析构:
char* pool = static_cast(::operator new(4096));
MyType* obj = new (pool) MyType{42}; // placement new
// ... 使用 obj ...
std::destroy_at(obj); // ✅ 正确:仅析构
::operator delete(pool); // ✅ 内存池整体释放(非 per-object)
关键点在于:析构与内存释放必须解耦。如果混用 delete obj,会尝试从 pool 地址调用 operator delete,大概率崩溃或泄漏。
立即学习“C++免费学习笔记(深入)”;