In How use alignof to force alignment for a heap allocation?, I asked how to use alignof
for heap-allocated objects. Now I'm generalizing my question for any way to force alignment of heap-allocated objects, because I can't find a way to do it using alignof
, std::aligned_storage
, or std::align
. The following code compiles, but neither VC12 nor Clang 3.2 produce the sequence of zeros as output that would indicate that my alignment request is being respected. (gcc 4.8.1 lacks std::align
, but if you comment that part out, the code compiles under gcc 4.8.1 and also produces output indicating that my alignment requests are being ignored.)
#include <iostream>
#include <memory>
int main()
{
// Try using alignas on the allocation
{
class Widget {};
for (int i = 0; i < 5; ++i)
{
auto ptr = new alignas(64) Widget;
std::cout << (long)ptr % 64 << '\n'; // should be 0
}
}
// Try using alignas on the type
{
class alignas(64) Widget {};
for (int i = 0; i < 5; ++i)
{
auto ptr = new Widget;
std::cout << (long)ptr % 64 << '\n'; // should be 0
}
}
// Try using std::aligned_storage
{
class Widget {};
using WidgetStorage_t =
std::aligned_storage<sizeof(Widget), 64>::type;
for (int i = 0; i < 5; ++i)
{
auto ptr = new WidgetStorage_t; // get buffer
new (ptr) Widget; // construct Widget
std::cout << (long)ptr % 64 << '\n'; // should be 0
}
}
// Try using operator new + std::align
{
class Widget {};
for (int i = 0; i < 5; ++i)
{
auto requestSize = // double space to ensure that a
2 * sizeof(Widget); // Widget fits after ptr adjustment
auto ptr = operator new(requestSize); // get buffer
std::align(64, sizeof(Widget), // align ptr
ptr, requestSize); // inside buffer
new (ptr) Widget; // construct Widget
std::cout << (long)ptr % 64 << '\n'; // should be 0
}
}
}
UPDATE: My code for testing std::align
is incorrect above. The following replacement code works:
// Try using operator new + std::align
{
class Widget {};
for (int i = 0; i < 5; ++i)
{
auto requestSize = // ensure that a
sizeof(Widget) + 64; // Widget fits after ptr adjustment
auto ptr = operator new(requestSize); // get buffer
std::align(64, sizeof(Widget), // align ptr
ptr, requestSize); // inside buffer
new (ptr) Widget; // construct Widget
std::cout << (long)ptr % 64 << '\n'; // should be 0
}
}
Is this the only way to get the job done? It's a lot more complicated than I'd like, because now two pointers have to be tracked: the adjusted one that points to the object (necessary to destroy the constructed object) and the unadjusted one that points to the memory buffer (necessary for releasing the memory).