When allocating an std::aligned_storage<2, 4096>::type
on the heap I always get a pointer that is offset by 16 bytes (on x64; on x86 it is offset by 8 bytes). In other words, this:
#include <iostream>
#include <cstddef>
int main() {
typedef std::aligned_storage<2, 4096>::type MemPage;
MemPage* p_mp = new MemPage;
std::cout << (void*)p_mp << std::endl;
return 0;
}
gives me (for example)
0x72f010
although I would expect all the last three digits to be zero. When allocating the std::aligned_storage<>::type
on the stack everything works as expected.
I use gcc-4.8.2 x86_64 on ubuntu 14.04.
It's not quite clear how the alignment requirements transpose to storage allocated with
new
. The standard maintains in [expr.new] that[basic.align]/3:
Over-aligned types might not be supported by GCC, and the "non-support" of this might (instead of a compiler error) lead to the allocation function only returning storage aligned with the strictest fundamental alignment:
sizeof(std::max_align_t)
. If the value of the latter is 16 on your machine, that would explain that the address is a multiple of 16.Also note that, despite the fact that runtime allocation functions will have maximum supported alignments,
operator new
can basically not take desired alignments into account as it has no parameter that could take the corresponding value and pass it on to the runtime environments allocation function. This problem is known and subject of an EWG-issue.Fun-fact: The above code is invoking UB. Consider the table in [meta.trans.ptr] that lists the requirements for
aligned_storage
s second template argument:If no type
T
has an alignment of4096
the requirement for the template argument is not fit. And what type would have an alignment of 212?However, this is not important to the essence of the question. We can just use
new
with an own typedef.