2011-11-28 66 views
7

我们可以使用placement new在预分配的内存中创建一个对象。在预先分配的内存中创建对象

让我们看看下面的例子:

char *buf = new char[1000]; //pre-allocated buffer 
string *p = new (buf) MyObject(); //placement new 
string *q = new (buf) MyObject(); //placement new 

我已经在预分配的缓冲区创建了两个对象。这两个对象是在缓冲区内随机创建的还是在连续的内存块中创建的?如果我们继续在缓冲区中创建更多的对象并希望它们存储在连续的内存块中,我们应该怎么做?首先在缓冲区中创建一个数组,然后在数组的元素插槽中创建每个对象?

+1

“如果我们在缓冲区中创建更多的对象,并希望它们存储在连续的内存块中,我们该怎么办?”使用'std :: vector',它是一个连续存储的动态数组。 – GManNickG

回答

5

这两个对象都在同一个内存位置创建,即buf。这是未定义的行为(除非对象是POD)。

如果要分配多个对象,则必须增加指针,例如, buf + n * sizeof(MyObject),但要小心对齐问题

也不要忘记当你完成后调用析构函数。

+1

由于缓冲区被分配了'new',它具有对齐以支持任何类型(包括数组)。 (不是说你一般都是错的,只是在这种情况下他是安全的。) – GManNickG

+0

@GMan:谢谢你,好点。如果你想把不同类型的对象放在内存中,我想还​​是需要额外的注意。 –

+0

+1顺便说一下,POD在这里的含义是什么? –

3

下面的代码行:

string *p = new(adr) MyObject(); 

将创建在地址ADR一个为MyObject对象。然后,下一次再创建一个对象,你就会知道,在ADR内存被使用的第一个对象,所以你的下一个目标将在adr + sizeof(MyObject)要创建:

string *q = new(adr + sizeof(MyObject)) MyObject(); 

的预分配存储点这样你就不会在运行时分配,这很慢。你在循环/程序开始时做一个大的分配,然后你只需要使用该分配的块。不利的一面是你必须管理你自己的内存,这意味着你必须找出把你的对象放在哪里会变得棘手,当你的内存池被分割时!

+0

if adr = static_cast (byteaddr)那么你会这样做:string * q = new(adr + 1)MyObject(); –