gpt4 book ai didi

c++ - 从新分配的内存分配给对象

转载 作者:太空狗 更新时间:2023-10-29 21:31:50 27 4
gpt4 key购买 nike

为数组分配行内存然后对该数组中的对象调用赋值运算符是否符合标准?

例如:

template <typename T>
void func(size_t sz, size_t pos)
{
static constexpr std::align_val_t __al = std::align_val_t(alignof(T));
T* data= static_cast<T*>(::operator new(sz * sizeof(T), __al));
data[pos] = T(1, 2); //is this legal? thechnically object at data[pos] is in some undetermenistic state.
}

最佳答案

这仅对标量类型(如数字类型或任何指针类型)或具有 "trivial" default constructor 的类类型(包括 union )有效,或此类类型的数组。如果 T 是具有非平凡默认构造函数或没有默认构造函数的类类型,或者此类类型的数组,则在未创建对象的内存上调用任何成员函数是未定义的行为,即使如果该成员是复制赋值运算符。

(当前的 C++20 草案在 [basic.life] 中有一些变化,似乎也排除了普通默认构造函数的情况,但我不完全确定其含义。)

执行此操作的正确且安全的方法是使用“placement new”:

template <typename T>
void func(size_t sz, size_t pos)
{
static constexpr std::align_val_t al = std::align_val_t(alignof(T));
std::byte* buffer = static_cast<std::byte*>(::operator new(sz * sizeof(T), al));
T* data = ::new(static_cast<void*>(buffer + pos*sizeof(T))) T(1, 2);
}

上面将参数 1, 2 直接传递给由 new 表达式调用的 T 的构造函数。如果该示例过于简单化并且您确实有一些其他原因来默认初始化对象(假设默认初始化是可能的)然后重新分配它,那也很简单:

template <typename T>
void func(size_t sz, size_t pos)
{
static constexpr std::align_val_t __al = std::align_val_t(alignof(T));
std::byte* buffer = static_cast<std::byte*>(::operator new(sz * sizeof(T), al));
T* data = ::new(static_cast<void*>(buffer + pos*sizeof(T))) T(1, 2);
// Whatever other logic...
data[pos] = T(1, 2);
}

关于c++ - 从新分配的内存分配给对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57103342/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com