9

We can use placement new to create an object in pre-allocated memory.

Let's consider the following example:

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

I've created two objects in the pre-allocated buffer. Are the two objects created randomly within the buffer or created in contiguous memory blocks? If we keep creating more objects in the buffer and want them to be stored in contiguous memory blocks, what should we do? Create an array in the buffer first and then create each object in the element slots of the array?

Terry Li
  • 16,870
  • 30
  • 89
  • 134
  • 1
    "If we keep creating more objects in the buffer and want them to be stored in contiguous memory blocks, what should we do?" Use `std::vector`, it is a contiguously stored dynamic array. – GManNickG Nov 28 '11 at 19:24

2 Answers2

8

The two objects are both created at the same memory location, namely buf. This is undefined behaviour (unless the objects are POD).

If you want to allocate several objects, you have to increment the pointer, e.g. buf + n * sizeof(MyObject), but beware of alignment issues

Also don't forget to call destructors when you're done.

Kerrek SB
  • 464,522
  • 92
  • 875
  • 1,084
  • 1
    Because the buffer was allocated with `new`, it has alignment to support any type (including arrays). (Not that you're wrong in general, just in this case he's safe.) – GManNickG Nov 28 '11 at 19:23
  • @GMan: Thanks, good point. I suppose extra attention is needed if you want to put objects of different types in the memory. – Kerrek SB Nov 28 '11 at 19:24
  • "Plain old data", i.e. a fundamental type, or arrays of PODs, or classes without constructors etc containing only PODs. Anything that's determined by its binary representation alone and can be memcopied. – Kerrek SB Nov 28 '11 at 20:55
5

The following line of code:

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

will create a MyObject object at the address adr. Then next time you create another object, you will know that the memory at adr is being used by the first object, so your next object will have to be created at adr + sizeof(MyObject):

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

The point of pre-allocated memory is so that you aren't allocating at runtime, which is pretty slow. You do one big allocation at the beginning of the loop/program and then you just have to use chunks of that allocation. The down side is that you have to manage your own memory which means you have to figure out where to put your objects which gets tricky when your memory pool gets fragmented!

Andrew Rasmussen
  • 14,912
  • 10
  • 45
  • 81