6

Many questions on SO ask about placement new feature of C++ (example 1, example 2) why it is used for. Many answers saying - custom allocating of objects like in pre-allocated spaces.

But question is - why need placement new for this? Won't just overload of operator new for class enough? By overload operator new for class I can exactly control where memory taken from - like call custom allocator. So why would I need placement new for this purpose?

Community
  • 1
  • 1
zaharpopov
  • 16,882
  • 23
  • 75
  • 93

4 Answers4

8

Placement New

Best example is to think about std::vector

How does std::vector put new items into an array?

When you add a new element to the end of an vector it must use placement new.

class MyVector
{
    char*  data;
    size_t size;

    MyVector() : size(0), data(new char[1000]) {}

    // Placement new copy construction of element into array.
    void push_back(T const& t) { new (data + (sizeof(T) * size)) T(t); ++size;}
};

Remember you can not use assignment or a simple copy because the element does not yet exist in the array (ie the memory space is not yet a T (its value is not defined)) so you must new to create a new T object in the array.

So think of placement new as a means of creating container objects. You can allocate more space than required for the container (and not initialize it). Then use placement new to initialize the elements as they are added.

Overload new

Overloading new allows you to control the space used when object have dynamic storage duration. Maybe your expected usage patterns do not fall under the normal usage patterns and you want to optimize creation/destruction. Maybe you want you want to build your own garbage collection (for a particular type).

The main different is that:

  • Overloading new controls the creation of space for 'dynamic storage duration` objects.
  • Placement new can be used for both dynamic and automatic storage duration objects (I suppose static as well). And is used externally to manage objects.

Overview:

Both are corner cases for the language and rarely used in normal code (I think I have written 2 new overloads and one class that uses placement new (for real production code/ does not include experiments and testing) in 15 years).

By the time you need to use these constructs in real life you will have been working with an experienced team for a couple of years that can validate your design.

Community
  • 1
  • 1
Martin York
  • 257,169
  • 86
  • 333
  • 562
  • good exmaple martin, but is it only for containers i want to prefer placement to overloading? – zaharpopov Jan 09 '11 at 10:32
  • @zaharpopov: Containers are just one case. Anytime you need to construct an object in a specific memory location, you do that using placement new. The object shouldn't need to overload `new` in order to be constructed somewhere specific. – Billy ONeal Jan 09 '11 at 10:48
  • @Billy: yes, I understand the intrusiveness argument from icecrime. was look for other reasons too – zaharpopov Jan 09 '11 at 10:50
  • thanks for good answer. ++. I accept icecrime because he first raised non-intrusive poiunt which is most I was thinking for – zaharpopov Feb 23 '11 at 05:12
  • @Nik-Lz: No the allocator simply allocates blank uninitialized memory. The vector must do the placement new. – Martin York Oct 28 '18 at 16:41
6

You are correct in thinking that both can be used to solve a same category of problems, but what you are missing is that operator new overloading is intrusive (allocation strategy is in the object), while placement new isn't (allocation strategy is completely independent).

Martin York's answer provides a great example in this regard : std::vector<> holds its very own allocation strategy without adding any requirement on the type T.

icecrime
  • 74,451
  • 13
  • 99
  • 111
0

Like other posters has said in the above links, placement new will place an object on an already allocated memory.

Overloading operator new for a class (or globally) will always take the memory from free list (either malloc or new). Of course, custom allocator can overload the new operator in such a way that it would use placement new internally.

But I do not see anyway how operator new can work as a replacement for ¨placement new¨. :-)

Also, since the subject of this question has keyword ¨versus¨, I reckon their is a notion of comparison between placement new and operator new. With that cognisance, please note that an object allocated via placement new necessitates a different strategy of ¨destructing¨ it: one must call the call the destructor on that object manually. (this is the only incidence in the language when programmer is mandated to call the destructor manually). In the case of overloaded operator new, an overloaded delete will be called, if supplied by the programmer. Their is no mandation here to call the destructor manually though: a simple ¨delete obj;¨ would do the trick.

Sorry for verbose answer but I hope you get the point.

Viren
  • 2,161
  • 22
  • 27
  • I don't understand "will always take the memory from free list". Can't your overloaded operator new to take memory from other place and not with malloc and new? Maybe some shared memory or prealloc buffer? – zaharpopov Jan 09 '11 at 10:30
-1

In custom allocators you'll be better off using the placement new to manage one big pre-allocated buffer in your custom way because of the performance. The standard heap implementation is horribly slow and if you allocate/deallocate a lot of objects of the same size a custom implementation might be a factor 1000 faster (without exaggerating)

The main reason for new for being slow is that it must be thread safe. So each access to the heap must be synchronized, what means if you have different threads often allocating/deallocating you will experience performance degradation. Also searching for blocks in the heap is not a cheap task.

A custom implementation with the placement new can be much faster if you know that all allocated blocks will be of the same size for example.

jdehaan
  • 19,700
  • 6
  • 57
  • 97
  • But you can also use overload of operator new for same purpose - hand out objects from prealloc big buffer. Hence my quesiton. What does your answer add to it? [Note I didn't -1 yet] – zaharpopov Jan 09 '11 at 10:31
  • @zaharpopov: Because when you overload `operator new`, you force all clients of the class to use that specific allocation strategy, whereas with some form of allocator the client is free to turn the "large chunk optimization" on and off. For example, maybe the client knows they're only going to create one or two objects, and don't want to pay for the large memory allocation. If you overloaded `operator new`, those clients are stuck. – Billy ONeal Jan 09 '11 at 10:51
  • @zaharpopov: no problem, I do not care about + or -1 :-) it's democracy. I think Billy ONeal gave the right answer: it's a matter of flexibility in the choice of an allocator. – jdehaan Jan 09 '11 at 14:15