Main Content

AUTOSAR C++14 Rule A18-5-10

Placement new shall be used only with properly aligned pointers to sufficient storage capacity

Since R2020b

Description

Rule Definition

Placement new shall be used only with properly aligned pointers to sufficient storage capacity.

Rationale

The new operator allocates the required amount of memory for storing an object on the heap and constructs a new object in the allocated memory in a single operation. If you want to separate the allocation and the construction and place an object in preallocated memory on either the stack or the heap, you use placement new. Placement new has advantages over new in certain situations, for example, when you need to place the object at a known memory location.

The new operator automatically allocates the correct amount of aligned memory that the object requires. But when using placement new, you must manually make sure that the pointer you pass has sufficient allocated storage capacity and is properly aligned. Violating these constraints results in the construction of an object at a misaligned location or memory initialization outside of allocated bounds, which might lead to unexpected or implementation-dependent behavior.

Polyspace Implementation

Suppose that a pointer ptr is preallocated m bytes of memory on the stack and has alignment n. For instance, if ptr is an array:

uint8_t ptr[5];
the allocated storage is sizeof(uint8_t) * 5 and the alignment is alignof(uint8_t). If you allocate more than m bytes to this pointer in a placement new expression or if the alignment required for the allocation is greater than n, the checker raises a violation. When determining the pointer alignment, the checker takes into account explicit alignments such as with std::align.

The checker does not consider pointers that are preallocated memory on the heap since the available storage depends on the memory availability, which is known only at run time.

Troubleshooting

If you expect a rule violation but Polyspace® does not report it, see Diagnose Why Coding Standard Violations Do Not Appear as Expected.

Examples

expand all

#include <new>
#include<memory>
#include <cstdint>

void Foo()
{
  uint8_t c;                
  uint64_t* ptr =
      new    // Non-compliant (insufficient storage, misaligned)
      (&c) uint64_t;
}

void Bar()
{
  uint8_t buf[sizeof(uint64_t)];    
  uint64_t* ptr =
      new            // Non-compliant (sufficient storage, misaligned)
      (buf) uint64_t;
}

void Baz()
{
  void* buf;
  std::size_t sp = 64;
  std::align(alignof(uint64_t), sizeof(uint64_t), buf, sp);
  uint64_t* ptr =
      new            // Compliant (sufficient storage, aligned)
      (buf) uint64_t;
}

In the function Foo, the &c points to an uint8_t value and has one byte memory in stack with one-byte alignment. The pointer is passed to placement new, which constructs an instance of uint64_t that requires 8 bytes of memory and a 4-byte alignment. This usage violates the rule.

In the function Bar, the pointer buf is properly allocated and has sufficient storage capacity. But, because it points to the uint8_t data type, it has one-byte alignment. This usage still violates the rule.

The function Baz calls the std::align function to create a pointer with correct storage capacity (8 byte) and alignment (4-byte) for uint64_t. This usage complies with the rule.

Check Information

Group: Language support library
Category: Required, Automated

Version History

Introduced in R2020b