Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: overhauled 'placement new' code examples

...

In this noncompliant code example, the local variable s1space is passed as the expression to the placement new operator. The resulting pointer of that call is then passed to ::operator delete(), resulting in undefined behavior due to ::operator delete() attempting to free memory that was not returned by ::operator new().

Code Block
bgColor#FFcccc
langcpp
#include <iostream>
 
struct S {
  S() { std::cout << "S::S()" << std::endl; }
  ~S() { std::cout << "S::~S()" << std::endl; }
};
 
void f() {
  char S s1space[sizeof(struct S)];
  S *s2s1 = new (&s1space) S;
 
  // ...
 
  delete s2s1;
}

Compliant Solution (placement new())

This compliant solution removes the call to ::operator delete(), allowing s1 to be destroyed as a result of its normal object lifetime terminationinstead explicitly calling s1's destructor. This is one of the few times when explicitly invoking a destructor is warranted.

Code Block
bgColor#ccccff
langcpp
#include <iostream>
 
struct S {
  S() { std::cout << "S::S()" << std::endl; }
  ~S() { std::cout << "S::~S()" << std::endl; }
};
 
void f() {
  char space[sizeof(struct S s1)];
  S *s2s1 = new (&s1space) S;
 
  // ...

  s1->~S();
}

Noncompliant Code Example (Uninitialized delete)

...