Reputation: 2972
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.
Upvotes: 7
Views: 1443
Reputation: 60999
It's not quite clear how the alignment requirements transpose to storage allocated with new
. The standard maintains in [expr.new] that
It is implementation-defined whether over-aligned types are supported (3.11).
[basic.align]/3:
An extended alignment is represented by an alignment greater than
alignof(std::max_align_t)
. It is implementation-defined whether any extended alignments are supported and the contexts in which they are supported (7.6.2). A type having an extended alignment requirement is an over-aligned type.
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:
Align
shall be equal toalignof(T)
for some typeT
or to default-alignment.
If no type T
has an alignment of 4096
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.
Upvotes: 9