You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 07:42:44