Search code examples
c++placement-new

Placement new using void* bits as storage


Assuming sizeof(T) <= sizeof(void*), is the following well defined / portable? ...

void* storage = 0;
new (&storage) T(t);

This seems like it could be used as a sensible small-object optimisation, if so.


Solution

  • You are passing a valid address, and if the memory pointed to is big enough to contain the object, and its alignment is compatible with that object, then it's perfectly fine code.

    The alignment should be implicitly correct if sizeof(T) <= sizeof(storage). But you can be paranoid about it and explicitly set it with:

    alignas(T) void* storage = 0;
    

    Although I think that manually setting the alignment isn't actually needed, and sizeof(T) <= sizeof(storage) would mean correct alignment is guaranteed, I'm not 100% sure.

    Note that just because the type of storage is void* doesn't mean anything. This particular placement new is defined by the standard as:

    void* operator new(std::size_t count, void* ptr);
    

    The address parameter is void*, meaning the type pointed to can be anything. The only requirement is that it's an address to valid memory.

    However, if storage ever goes out of scope, you're busted if the object contained within needs to be destructed. You need to call the destructor before storage goes out of scope.

    Also note that "placement delete" (this is automatically called if needed, it's not possible to write code that does it) will never actually free memory. So storage being on the stack is still fine even if placement delete gets called (like when a constructor throws.)