Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

At what point does the lifetime of a trivial type created by placement-new start?

During a dive into dynamic memory, it occurred to me it appears contradictory how trivial types begin their lifetime. Consider the snippet

void* p = ::operator new(sizeof(int));  // 1
// 2
new (p) int; // 3

When does the int start its lifetime?

  1. Only acquires storage, ::operator new is specified to have the effect (from [new.delete.single])

    The allocation functions called by a new-expression to allocate size bytes of storage. [...] allocates storage suitably aligned to represent any object of that size provided the object's type does not have new-extended alignment.

    Given that acquiring storage is insufficient in creating an object, the int cannot have begin its lifetime here.

  2. At this point, suitbale storage for the int has been acquired.

  3. The int is created by placement new. But somehow its lifetime didn't begin here, since from [basic.life]

    [...] An object is said to have non-vacuous initialization if it is of a class or aggregate type and it or one of its subobjects is initialized by a constructor other than a trivial default constructor. The lifetime of an object of type T begins when:

    • storage with the proper alignment and size for type T is obtained, and

    • if the object has non-vacuous initialization, its initialization is complete [...]

    int is neither a class nor aggregate type, hence it has vacuous initialization. Therefore only the first bullet applies. However, this is clearly not when storage is obtained and therefore cannot be when its lifetime starts.

Some context

Allocators are required to return memory without constructing its elements. Yet this doesn't make sense with trivial types. The effects of a.allocate(n) with a an allocator object for type T is

Memory is allocated for n objects of type T but objects are not constructed.

like image 716
Passer By Avatar asked Feb 28 '18 20:02

Passer By


People also ask

What is the lifetime of an object and how can you extend the lifetime of an object?

The lifetime of a temporary object may be extended by binding to a const lvalue reference or to an rvalue reference (since C++11), see reference initialization for details.

What is the lifetime of an object in c++?

C/C++ use lexical scoping. The lifetime of a variable or object is the time period in which the variable/object has valid memory. Lifetime is also called "allocation method" or "storage duration."


1 Answers

Technically, the new-expression always obtains storage. The code new(p) int both obtains storage and creates an object, and according to [basic.life]/1, the object's lifetime began when new(p) int obtained the storage.

According to N4659 [expr.new], the code new(p) int generates a call to an allocation function ::operator new(sizeof(int), p). And under [new.delete.placement], the standard library defines such a function:

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

Returns: ptr.

Remarks: Intentionally performs no other action.

Although "no other action" is performed, and probably the implementation will optimize out any actual function call, this call to an allocation function still counts as obtaining storage for the object being created by the new-expression.

like image 193
M.M Avatar answered Oct 13 '22 01:10

M.M