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

哪些操作会触发指定存储位置对象的生命周期终止?

C++对象生命周期终止问题解析

场景示例

#include <array>
#include <cstddef>
#include <cstdint>
#include <memory>

struct S {
    alignas(std::uint64_t) alignas(std::uint32_t)
    std::array<std::byte, sizeof(std::uint64_t)> storage =
        { /* some init values */ };
};

int main() {
    S s;

    // 显式在存储位置创建uint64_t对象
    auto pi64 = std::start_lifetime_as<std::uint64_t>(s.storage.data());

    // 显式在同一存储位置创建uint32_t对象
    auto pi32 = std::start_lifetime_as<std::uint32_t>(s.storage.data());
}

核心问题解答

1. 第二次调用std::start_lifetime_as是否会终止之前的uint64_t对象生命周期?

是的。根据C++标准,当在已被某个对象占用的存储区域上创建新对象时,只要新对象的存储与原有对象的存储存在重叠,原有对象的生命周期立即终止——无论新对象的大小是否完全覆盖原有对象的存储。

示例中,两次std::start_lifetime_as调用都以storage.data()作为起始地址,新创建的uint32_t对象与之前的uint64_t对象存储区域重叠,因此原有uint64_t的生命周期被终止。

2. 还有哪些操作会触发此类生命周期终止?

以下是几种常见的触发原有对象生命周期终止的操作:

  • Placement new表达式:直接在原有对象的存储位置构造新对象,比如你提到的new (storage.data()) std::byte[sizeof(std::uint64_t)],只要存储区域重叠,原有对象的生命周期就会终止。
  • std::construct_at函数:该函数是placement new的封装,用于在指定地址构造新对象,同样会终止重叠存储上的原有对象生命周期。
  • 联合(Union)成员切换:当激活联合的另一个成员时,当前活跃成员的生命周期会终止(对于非平凡类型,需先显式调用析构函数;平凡类型无需额外操作)。
  • 隐式生命周期类型的存储覆盖:对于std::byte、char、unsigned char这类隐式生命周期类型,直接覆盖其存储内容并将该存储用作其他对象的存储时,原有对象(如果存在)的生命周期会自动终止。
  • std::start_lifetime_as_array函数:与std::start_lifetime_as类似,用于在指定地址创建数组对象,同样会终止重叠存储上的原有对象生命周期。

注意:对于非平凡类型,在终止其生命周期前建议显式调用析构函数,避免资源泄漏(placement new、std::construct_at等操作不会自动析构原有对象)。

内容的提问来源于stack exchange,提问作者Oersted

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 01:27:05