在How use alignof to force alignment for a heap allocation?中,我询问如何将alignof
用于堆分配的对象。现在我正在概括我的问题任何方式来强制对齐堆分配的对象,因为我找不到使用alignof
,std::aligned_storage
的方法,或std::align
。下面的代码编译,但VC12和Clang 3.2都没有产生零序列作为输出,表明我的对齐请求正在被尊重。 (gcc 4.8.1缺少std::align
,但如果你对该部分进行注释,代码将在gcc 4.8.1下编译,并产生输出,表明我的对齐请求被忽略。)
#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
}
}
}
更新:我上面的测试代码std::align
不正确。以下替换代码有效:
// 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
}
}
这是完成工作的唯一方法吗?它比我想要的复杂得多,因为现在必须跟踪两个指针:指向对象的调整指针(破坏构造对象所必需的)和指向内存缓冲区的未调整指针(释放所需的指针)记忆)。
答案 0 :(得分:1)
我在实践中看到的一个选项是过度分配,然后为自己调整一些东西。
例如,假设您要分配与 M 字节边界对齐的 N 字节。您可以继续分配 N + M-1 字节,然后在分配的空间中找到第一个 M 字节对齐的地址。例如,您可以执行以下操作:
const size_t N = sizeof(Widget);
const size_t M = 64;
char *pc = new char[N+M-1];
char *pc_aligned = (pc+M-1)&(~(M-1));
Widget *p = new (pc_aligned) Widget(); // placement new
// ...
p->~Widget(); // explicitly call destructor
delete [] pc; // delete array allocated with new
答案 1 :(得分:0)
MS明确指出C ++ 11 alignas
未在http://msdn.microsoft.com/en-us/library/hh567368.aspx
对于GNU - 如果你把它放在正确的位置似乎是有效的 - 从Where can I use alignas() in C++11?只是一种品味 - 看到更多例子和讨论的答案:
typedef float aligned_block alignas(16) [4];
typedef float aligned_block [4] alignas(16);