views:

1363

answers:

14

I just learned about the C++ construct called "placement new". It allows you to exactly control where a pointer points to in memory. It looks like this:

 #include <new>        // Must #include this to use "placement new"
 #include "Fred.h"     // Declaration of class Fred

 void someCode()
 {
   char memory[sizeof(Fred)];
   void* place = memory;

   Fred* f = new(place) Fred();   // Create a pointer to a Fred(),
                                  // stored at "place"

   // The pointers f and place will be equal

   ...
 }

(example from C++ FAQ Lite)

In this example, the this pointer of Fred will be equal to place.


I've seen it used in our team's code once or twice. In your experience, what does this construct enable? Do other pointer languages have similar constructs? To me, it seems reminiscent of equivalence in FORTRAN, which allows disparate variables to occupy the same location in memory.

+3  A: 

I use this construct when doing C++ in kernel mode.

I use the kernel mode memory allocator and construct the object on the allocated chunk.

All of this is wrapped in classes and functions, but in the end I do a placement new.

Edouard A.
+1  A: 

It can be useful when paging out memory to a file on the hard drive, which one might do when manipulating large objects.

Tommy Herbert
Can you elaborate on that? Useful for paging out? Or useful for paging back in? I see the paging back in, not quite imagining the paging out.
ApplePieIsGood
+4  A: 

Placement new can be used to create type-safe unions, such as Boost's variant.

The union class contains a buffer as big as the biggest type it's specified to contain (and with sufficient alignment). It placement news objects into the buffer as required.

James Hopkin
+9  A: 

It is also used for embedded programming, where IO devices are often mapped to specific memory addresses

Nemanja Trifunovic
+9  A: 

It allows you to do your own memory management. Usually this will get you at best marginally improved performance, but sometimes it's a big win. For example, if your program is using a large number of standard-sized objects, you might well want to make a pool with one large memory allocation.

This sort of thing was also done in C, but since there are no constructors in C it didn't require any language support.

David Thornley
The problem you are describing should be solved by using the appropriate memory allocator, overloading placement new might not be the best course of action.
Edouard A.
Correct -- when using the template library. Otherwise, there's placement new.
jmucchiello
Sure, there's lots of places in C++ where there's now a better way to do it. I haven't written delete [] in years, for example. However, there's a lot of older code around that does use placement new and such.
David Thornley
A: 

seems to me like a way of allocating an object on the stack ..

hasen j
Well, that's what vanilla new does, but usually you don't get to specify where on the stack.
Tommy Herbert
Tommy: you're thinking of the heap
James Hopkin
Well in the original posted question above, it does in fact end up newing on the stack, because the array buffer created is on the stack. But that does not have to be the case. Perhaps a better example would have used heap allocated memory with malloc()...
ApplePieIsGood
+6  A: 

I've used it when constructing objects in a shared memory segment.

Greg Rogers
A: 

I've used it to construct dynamically allocated stack arrays.

Ferruccio
A: 

Try this: Placement new

Naveen
Yeah, you might notice a similarity between my example and the example in that FAQ. ;)
Scottie T
+4  A: 

Its usefull when building your own container like objects.

For example if you were to create a vector. If you reserve space for a large number of objects you want to allocate the memory with some method that does not invoke the constructor of the object (like new char[sizeof(object) * reserveSize]). Then when people start adding objects into the vector you use placement new to copy them into allocated memory.

template<typename T>
class SillyVectorExample
{
    public:
        SillyVectorExample()
            :reserved(10)
            ,size(0)
            ,data(new char[sizeof(T) * reserved])
        {}
        void push_back(T const& object)
        {
            if (size >= reserved)
            {
                // Do Somthing.
            }
            // Place a copy of the object into the data store.
            new (data+(sizeof(T)*size))  T(object);
            ++size;
        }
        // Add other methods to make sure data is copied and dealllocated correctly.
    private:
        size_t   reserved;
        size_t   size;
        char*    data;
 };

PS. I am not advocating doing this. This is just a simplified example of how containers can work.

Martin York
Do you have any more concrete examples of when you would actually use this?
Scottie T
What do you mean more concrete? Containers are a good example. I am sure the STL containers that need to reserve space will use placement new in some form(probably via the allocaters but I have not looked so this is just an assumption).
Martin York
+1  A: 

Placement new allows the developer to allocate the memory from preallocated memory chunk. If the system is larger, then developers go for using placement new. Now I am working on a larger avionics software there we allocate the large memory that is required for the execution of application at the start. And we use the placement new to allocate the memory wherever required. It increases the performance to some amount.

Vinay
+4  A: 

Placement new is NOT about making pointers equal (you can just use assignment for that!).

Placement new is for constructing an object at a particular location. There are three ways of constructing an object in C++, and placement new is the only one that gives you explicit control over where that object "lives". This is useful for several things, including shared memory, low-level device I/O, and memory pool/allocator implementation.

With stack allocation, the object is constructed at the top of the stack, wherever that happens to be currently.

With "regular" new, the object is constructed at an effectively arbitrary address on the heap, as managed by the standard library (unless you've overridden operator new).

Placement new says "build me an object at this address specifically", and its implementation is simply an overload of operator new that returns the pointer passed to it, as a means of getting to the remainder of the machinery of the new operator, which constructs an object in the memory returned by the operator new function.

It's also worth noting that the operator new function can be overloaded with arbitrary arguments (just as any other function). These other arguments are passed via the "new(arg 2, arg3, ..., argN)" syntax. Arg1 is always implicitly passed as "sizeof(whatever you're constructing)".

Drew Hall
A: 

I've used it to create objects based on memory containing messages received from the network.

Steve Fallows
+1  A: 

By controlling the exact placement, you can align things in memory and this can sometimes be used to improve CPU fetch/cache performance. Never actually saw it in use, though

Uri