gpt4 book ai didi

c++ - 在分配为不同类型的数组上使用 delete[] 是否安全?

转载 作者:搜寻专家 更新时间:2023-10-31 01:40:36 25 4
gpt4 key购买 nike

为了使用 placement new 而不是自动尝试调用默认构造函数,我使用 reinterpret_cast<Object*>(new char[num_elements * sizeof(Object)]) 分配一个数组而不是 new Object[num_elements] .

但是,我不确定应该如何删除数组以便正确调用析构函数。我是否应该遍历元素,为每个元素手动调用析构函数,然后将数组转换为 char*并使用 delete[]就此而言,像这样:

for (size_t i = 0; i < num_elements; ++i) {
array[i].~Object();
}
delete[] reinterpret_cast<char*>(array);

或者如果我不为每个元素手动调用析构函数就足够了,而只是依靠 delete[] 来做到这一点,因为数组的类型是 Object* , 比如 delete[] array

我担心的是,并非每个平台都能够以这种方式正确确定数组中的元素数量,因为我没有使用类型分配数组合适的大小。 An answer关于“delete[] 如何知道操作数的大小”的问题表明 delete[] 的可能实现将存储分配的元素数(而不是字节数)。

如果delete[]确实是这样实现的,这表明只使用 delete[] array会尝试删除太多元素,因为数组是用更多 char 创建的元素比多少Object元素适合它。所以在那种情况下,删除数组的唯一可靠方法是手动调用析构函数,将数组转换为 char*。 , 然后使用 delete[] .

但是,实现它的另一种合乎逻辑的方法是以字节为单位存储数组的大小,而不是元素的数量,然后在调用delete[] 时使用。 ,将数组的大小除以类型的大小以获得要调用其析构函数的元素的数量。如果使用此方法,则只需使用 delete[] array其中 array有一个类型 Object*就足够了。

所以我的问题是:如果数组最初没有分配正确的类型,我能否依靠 delete[] 正确调用操作数数组中元素的析构函数?


这是我正在使用的代码:

template <typename NumberType>
NeuronLayer<NumberType>::NeuronLayer(size_t num_inputs, size_t num_neurons, const NumberType *weights)
: neurons(reinterpret_cast<Neuron<NumberType>*>(new char[num_neurons * sizeof(Neuron<NumberType>)])),
num_neurons(num_neurons), num_weights(0) {
for (size_t i = 0; i < num_neurons; ++i) {
Neuron<NumberType> &neuron = neurons[i];
new(&neuron) Neuron<NumberType>(num_inputs, weights + num_weights);
num_weights += neuron.GetNumWeights();
}
}

template <typename NumberType>
NeuronLayer<NumberType>::~NeuronLayer() {
delete[] neurons;
}

template <typename NumberType>
NeuronLayer<NumberType>::~NeuronLayer() {
for (size_t i = 0; i < num_neurons; ++i) {
neurons[i].~Neuron();
}
delete[] reinterpret_cast<char*>(neurons);
}

最佳答案

Object* 上调用 delete[] 将为 new[] 分配的每个对象调用一次析构函数。 new Object[N] 通常在实际数组之前存储 N,delete[] 当然知道去哪里查找。

您的代码不存储该计数。它不能,因为它是一个未指定的实现细节,其中以及如何存储计数。正如您推测的那样,有两种明显的方式:元素计数和数组大小,以及一种明显的位置(在数组之前)。即便如此,也可能存在对齐问题,并且您无法预测尺寸使用的是什么类型。

此外,new unsigned char[N] 是一种特殊情况,因为 delete[] 不需要调用 char 的析构函数。在这种情况下,new[] 根本不需要存储 N。因此,即使 new Object[N] 会存储一个大小,您甚至不能指望存储该大小。

关于c++ - 在分配为不同类型的数组上使用 delete[] 是否安全?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29593132/

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