开发者

c++ placement new vs. overloading new

开发者 https://www.devze.com 2023-02-03 01:34 出处:网络
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.

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 ne开发者_StackOverflow中文版ed 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?


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.


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.


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.


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.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号