Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: minor editorial changes

When invoked by a new expression for a given type, the default global non-placement forms of C++ operator new attempt to allocate sufficient storage for an object of the type and, if successful, return a pointer with alignment suitable for any object with a fundamental alignment requirement. However, the default placement new operator simply returns the given pointer back to the caller without guaranteeing that there is sufficient space in which to construct the object or ensuring that the pointer meets the proper alignment requirements. The C++ Standard, [expr.new], paragraph 16 [ISO/IEC 14882-2014], nonnormatively states the following:

[Note: when the allocation function returns a value other than null, it must be a pointer to a block of storage in which space for the object has been reserved. The block of storage is assumed to be appropriately aligned and of the requested size. The address of the created object will not necessarily be the same as that of the block if the object is an array. —end note]

...

In addition, the standard provides the following example later on in the same section:

new(2, f) T[5] results in a call of operator new[](sizeof(T) * 5 + y, 2, f).

Here, ... and y are non-negative unspecified values representing array allocation overhead; the result of the new-expression will be offset by this amount from the value returned by operator new[]. This overhead may be applied in all array new-expressions, including those referencing the library function operator new[](std::size_t, void*) and other placement allocation functions. The amount of overhead may vary from one invocation of new to another.

...

In this compliant solution, the alignas declaration specifier is used to ensure the buffer is appropriately aligned for a long:.

Code Block
bgColor#ccccff
langcpp
#include <new>
 
void f() {
  char c; // Used elsewhere in the function
  alignas(long) unsigned char buffer[sizeof(long)];
  long *lp = ::new (buffer) long;
 
  // ...
}

...

This compliant solution ensures that the long is constructed into a buffer of sufficient size and with suitable alignment:.

Code Block
bgColor#ccccff
langcpp
#include <new>
 
void f() {
  char c; // Used elsewhere in the function
  std::aligned_storage<sizeof(long), alignof(long)>::type buffer;
  long *lp = ::new (&buffer) long;
 
  // ...
}

...