C++标准是否允许在对象销毁后、内存释放前使用其提供的存储?
C++标准相关疑问:对象销毁后内存未释放时的存储使用合法性
核心疑问
C++标准是否允许在对象销毁但内存尚未释放时,使用该对象提供的存储?
常规场景下,对象销毁后其存储可被复用,但下述特殊场景存在疑问:模板结构体B为模板参数T类型对象提供存储,并在自身构造时于该存储中构造T对象。当B对象被销毁时,其存储中的T类型对象(示例中的A)并未被销毁,而提供存储的std::byte数组因析构函数平凡无副作用,生命周期未结束。由此产生疑问:A类型对象的生命周期是否随B一同结束?
示例代码
#include <cstddef> #include <iostream> #include <memory> #include <new> struct A { int i = 23; }; template<class T> struct B { B() { // 在预留存储中构造T对象 new (&c) T; } // 返回存储中对象的引用 T & t() { return *std::launder(reinterpret_cast<T *>(&c)); } // 预留的存储 alignas(T) std::byte c[sizeof(T)]; }; int main() { using Alloc = std::allocator<B<A>>; using AllocTraits = std::allocator_traits<Alloc>; Alloc alloc; // 存储生命周期开始 B<A> * b = AllocTraits::allocate(alloc, 1u); // 构造B和A对象 AllocTraits::construct(alloc, b); // 获取A的引用 A & a = b->t(); std::cout << "此时A存活。a.i = " << a.i << std::endl; a.i = 42; // B对象被销毁,但A未被销毁 AllocTraits::destroy(alloc, b); // 读取'a'是否属于未定义行为? std::cout << "A是否仍存活?a.i = " << a.i << std::endl; // 销毁A a.~A(); // 存储生命周期结束 AllocTraits::deallocate(alloc, b, 1u); return 0; }
延伸问题与解答
问:为何有人会这么做?
答:这种方式可用于实现无额外开销的侵入式弱指针控制块。
内容的提问来源于stack exchange,提问作者woodstock
相关产品推荐
相关产品推荐

