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

如何动态生成不可默认构造对象的连续序列并使用delete[]销毁?

不可默认构造类的堆上连续对象创建与销毁方案

定义说明

标识符含义
T不可默认构造的类,所有构造函数非公开
gen返回T类型对象的友元函数,可假设为noexcept
n正size_t类型值

需求描述

通过gen函数在堆上生成连续的n个T对象,要求后续能完成所有对象销毁与内存释放。若T可默认构造,直接使用数组new即可:

T* my_t_objects = new T[n];

之后调用delete[] my_t_objects即可完成操作,但T不可默认构造时无法使用该方式,需针对两种gen形式实现方案:

  1. 无参数gen:T gen()
  2. 带索引参数gen:T gen(size_t)

用户初步思路:先分配n个T的内存,再通过placement-new逐个构造对象,但不确定对该T*指针调用delete[]是否有效。

注意事项

  • 禁止使用std::vector<T>和std::generate
  • 优先提供C20之前的兼容方案,也可接受C20及以上版本方案

解决方案

核心结论

直接对placement-new构造的T*指针调用delete[]属于未定义行为:delete[]要求指针必须来自同类型数组的new[]分配,而手动分配内存后构造的对象不满足该条件,且delete[]无法获取数组大小以完成所有对象的析构。正确流程为:手动分配对齐内存→逐个构造对象→逐个析构对象→释放原始内存。

通用基础实现(C++11及以上)

情况1:无参数gen

// 分配满足T对齐要求的内存块,大小为n个T的总字节数
alignas(T) char* raw_memory = new char[n * sizeof(T)];
T* obj_array = reinterpret_cast<T*>(raw_memory);

// 逐个构造对象
for (size_t i = 0; i < n; ++i) {
    // placement-new调用gen()构造T对象
    new (obj_array + i) T(gen());
}

// 此处可正常使用obj_array指向的连续对象数组

// 销毁与释放
for (size_t i = 0; i < n; ++i) {
    // 手动调用每个对象的析构函数
    obj_array[i].~T();
}
// 释放原始内存块
delete[] raw_memory;

情况2:带索引参数gen

仅构造逻辑需传入索引,其余流程与情况1一致:

alignas(T) char* raw_memory = new char[n * sizeof(T)];
T* obj_array = reinterpret_cast<T*>(raw_memory);

for (size_t i = 0; i < n; ++i) {
    new (obj_array + i) T(gen(i)); // 传入索引生成对应对象
}

// 使用对象数组...

// 销毁与释放
for (size_t i = 0; i < n; ++i) {
    obj_array[i].~T();
}
delete[] raw_memory;

C++20优化实现

使用C++20标准库的std::construct_at和std::destroy_at替代手动placement-new与析构调用,写法更简洁规范:

#include <memory>

// 情况1示例
alignas(T) char* raw_memory = new char[n * sizeof(T)];
T* obj_array = reinterpret_cast<T*>(raw_memory);

for (size_t i = 0; i < n; ++i) {
    std::construct_at(obj_array + i, gen());
}

// 使用对象数组...

for (size_t i = 0; i < n; ++i) {
    std::destroy_at(obj_array + i);
}
delete[] raw_memory;

// 情况2仅需将construct_at的参数改为gen(i)即可

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 15:32:15