我需要从先前分配的内存块构造一个对象数组。但是,在分配该块时,我无法从用户的角度理解::operator new[]()
与::operator new()
的不同之处,因为两者都需要块的大小。在下面的示例中,使用任何一个似乎都具有相同的效果。我错过了什么吗?
class J {
};
int main() {
const int size = 5;
{
J* a = static_cast<J*> (::operator new[](sizeof (J) * size));
for (int i = 0; i < size; i++)
new (&a[i]) J();
for (int i = 0; i < size; i++)
a[i].~J();
::operator delete[] (a);
}
{
J* a = static_cast<J*> (::operator new(sizeof (J) * size));
for (int i = 0; i < size; i++)
new (&a[i]) J();
for (int i = 0; i < size; i++)
a[i].~J();
::operator delete (a);
}
}
答案 0 :(得分:3)
您滥用new
。
使用new []
的关键是它为被分配的数组的每个元素调用构造函数。 delete[]
对析构函数也是如此。
您正在使用展示位置new
并手动调用构造函数和析构函数,错过了整点。
答案 1 :(得分:3)
它们都是分配函数,因此它们都被要求返回所需大小的合适存储空间(这里是sizeof(J) * size
)。这就是为什么它们对你的代码没有任何影响。
它们的区别在于operator new
是在非数组新表达式(例如new J
)中查找的分配函数,而operator new[]
是在数组 new expression (例如new J[1]
)中查找的分配函数。如果程序具有为不同于为单个对象分配内存的策略的数组分配内存的特定策略,则允许自定义。如果不需要这样的自定义,那么operator new[]
可以委托给operator new
(这实际上是对实现提供的分配函数的强制要求,即::operator new
和{{1} })。因此,这种差异与您的代码无关。