new
for over-aligned types CXX-W2018The global operator new
is called it allocates storage for any object of the
specified size, and it is only guaranteed to have a suitable alignment for
objects with a fundamental alignment requirement, and not for over-aligned
types. One can specify the alignment requirement while declaring a C++ record
using the keyword alignas
as shown in the examples below. Such C++ records,
with user-specified alignment, are called over-aligned types.
It is recommended that one should implement the operator new()
for over-aligned
types and avoid using the default implementation of new
. This is because such
a practice could cause the objects to be constructed at a location that is
misaligned, which is an undefined behavior and can lead to abnormal termination
when the object is accessed. This risk remains even on architectures that are
otherwise capable of tolerating misaligned accesses.
struct alignas(128) ARecord {
char elems[128];
};
ARecord* getRecords() {
ARecord *pv = new ARecord; // A misaligned memory allocation
return pv;
}
#include <cstdlib>
#include <new>
struct alignas(128) ARecord {
char elems[128];
static void *operator new(size_t nbytes) {
if (void *p = std::aligned_alloc(alignof(ARecord), nbytes)) {
return p;
}
throw std::bad_alloc();
}
static void operator delete(void *p) {
free(p);
}
};
ARecord *f() {
// A call to overloaded operator `new` to make sure the alignment is okay
ARecord *pv = new ARecord;
return pv;
}