新和新 [] 返回的内存上的新放置

Placement new on memory returned by new and new[]

本文关键字:新放 内存 返回      更新时间:2023-10-16

下面是我的测试类:-

class Base
{
public:
    int data;
    Base(int x) : data(x) {}
};

现在,我正在使用放置新在已分配的内存上创建对象:-

CASE_1:-

void* raw = operator new(4* sizeof(Base));
Base* b = static_cast<Base*>(raw);
for(int i = 0; i < 4; i++)
    new (&b[i]) Base(i);

CASE_2:-

void* raw = operator new[](4* sizeof(Base));  <<<<<<<<<<<<<
Base* b = static_cast<Base*>(raw);
for(int i = 0; i < 4; i++)
    new (&b[i]) Base(i);

在CASE_1中,我使用普通new来分配足够的内存,而在Case_2中,我使用new[]来分配。正如我测试的那样,两者都工作正常:-

for(int i = 0; i < 4; i++)
{
    Base* b1 = b;
    cout << (*(b1+i)).data;
}

但是,我很困惑CASE_1是否是为对象数组进行内存分配的正确方法。这两种方法是否相似。

引用

此页面:

默认定义通过调用运算符 new 来分配内存:::运算符 new(大小)。

由此判断,结果应该完全一样。两行应返回相同的指针。

正如@Joachim Pileborg指出的那样,您可能应该避免operator new并使用更简单的new Base[4]

回答这个问题的困难在于,在使用放置之前,必须有一些"非常奇怪的事情"在起作用 new 是个好主意。如果不知道那是什么,就很难自信地说你正在做的事情是"正确的"。

他们两者都做。

使用全局operator new[]是相当没有意义的。它为您提供的全局operator new只是您(或程序中的其他一些代码)能够重载它们以执行不同的事情,例如从不同的来源分配。因此,您可能会认为将operator new[]用于可能较大的分配是更好的做法,然后您可以在程序的其他位置针对该目的进行优化。但与直接将特定分配器用于特定目的相比,这是一个相当生硬的工具。我真的不认为这很常见,但是使用全局新并不常见。

此外,您不会显示释放内存的代码,因此有很多机会出错。通常,必须依次调用每个元素的析构函数,然后调用与使用的新运算符匹配的全局删除运算符。对于您的特定类Base,未能销毁它实际上没有害处,但是如果您省略析构函数调用并稍后更改Base则可能会遇到麻烦。