Found using default opertor `new` for over-aligned typesCXX-W2018
The 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.
Bad practice
struct alignas(128) ARecord {
char elems[128];
};
ARecord* getRecords() {
ARecord *pv = new ARecord; // A misaligned memory allocation
return pv;
}
Recommended
#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;
}