Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Fixing the code example and wordsmithing

...

Code Block
bgColor#FFcccc
langcpp
#include <new>

struct S {
  void *p;
  S ();
  ~S ();
};

void f() {
  const unsigned N = 32;
  alignas (S) unsigned char buffer[sizeof(S) * N];
  S *sp = ::new (buffer) S [N];
 
  // ...
  // Destroy elements of the array.
  for (size_t i = 0; i != n; ++i) {
    sp[i].~S();
  }
}

Compliant Solution (Clang / G++)

The amount of overhead required by array new expressions is unspecified but should be documented by quality implementations. The following compliant solution is portable to the Clang and GNU GCC compilers. Porting it to other implementations requires adding similar conditional definitions of the overhead constant. When an implementation does not document the overhead, assuming it is at least as large as twice the size of sizeof(size_t) should typically be safe. To verify that the assumption is, in fact, safe, the compliant solution defines an overload of the placement new[] operator that accepts the buffer size as a third argument and verifies that it is at least as large as the total amount of storage required.

Code Block
bgColor#ccccff
langcpp
#include <cassert><cstddef>
#include <cstddef><new>

#if __clang__ || __GNUG__
  const size_t overhead = sizeof(size_t);
#else
  const size_t overhead = 2 * sizeof(size_t);
#endif

struct S {
  void *p;
  S();
  ~S();
};

void * operator new[] (size_t n, void *p, size_t bufsize) {
  assertif (n <= bufsize); {
  // alternatively, throw an exception std::bad_array_new_length();
  }
  return p;
}

void f() {
  const size_t n = 32;
  alignas(S) unsigned char buffer[sizeof(S) * n + overhead];
  S *sp = new (buffer, sizeof (buffer)) S[n];
 
  // ...
  // Destroy elements of the array.
  for (size_t i = 0; i != n; ++i) {
    sp[i].~S();
  }
}

...