In addition to Ben Voigt, answer what details, when it's normal, to omit the call to the destructor, it is important to ensure that the memory alignment is correct for the type to be placed - new in it. I will try to write it here as requested by OP .
This line:
S *newS = new(buffer + offset)S;
only works if the buffer + offset
address is correctly aligned:
3.11 Alignment
1 Types of objects have alignment requirements (3.9.1, 3.9.2), which establish restrictions on the addresses at which an object of this type can be selected. Alignment is an integer value defined by the implementation that represents the number of bytes between consecutive addresses where this object can be allocated.
[...]
buffer
itself is correctly aligned for any type with a fundamental alignment requirement:
3.7.4.1 Distribution Functions
2 [...]
The returned pointer must be properly aligned so that it can be converted to a pointer to any complete object type with a fundamental alignment requirement (3.11) and then used to access the object or array in a dedicated storage [...]
To find out the alignment requirement for a type, there is alignof(type)
. Then there is std::max_align_t
, alignof(std::max_align_t)
returns the highest alignment value of all types with a fundamental alignment requirement.
There is a special case of types that require extended alignment so that your type is not one of them; I would include it in your program:
static_assert(alignof(S) <= alignof(std::max_align_t), "Extended alignment required for S");
Then you need to make sure that offset
multiple of alignof(S)
.
alain source share