C++ 如何使用alignof强制堆分配的对齐?

C++ 如何使用alignof强制堆分配的对齐?,c++,c++11,memory-alignment,C++,C++11,Memory Alignment,我想强制特定的堆分配返回64字节对齐的地址,因为这是缓存线边界。我想我可以这样做 int *p = new alignas(64) int; 但是我的编译器中似乎没有一个给p的地址是64的倍数。我是这样检查的: #include <iostream> int main() { int *p = new alignas(64) int; std::cout << long(p) % 64 << '\n'; // should print 0 }

我想强制特定的堆分配返回64字节对齐的地址,因为这是缓存线边界。我想我可以这样做

int *p = new alignas(64) int;
但是我的编译器中似乎没有一个给
p
的地址是64的倍数。我是这样检查的:

#include <iostream>

int main()
{
  int *p = new alignas(64) int;
  std::cout << long(p) % 64 << '\n';    // should print 0
}
#包括
int main()
{
int*p=新的对齐方式(64)int;

std::cout请求比您需要的多64个字节,然后在分配的空间内生成一个与缓存对齐的地址。最后注意释放整个分配的内存。

new
操作符调用以分配空间的分配器是“假定返回指向存储器的指针,该存储器针对任何类型的具有基本属性的对象进行适当对齐 对齐“(§3.7.4.1/2;引用自§5.3.4/11)。
alignas(64)
可能不是编译器和环境的“基本对齐”,因此分配函数不需要遵守它

请注意,分配函数只传递请求的空间量;它不知道请求的对齐方式。因此,它无法调整其结果以满足特殊需要


alignas
类型说明符设计用于处理静态和自动对象。对于此类对象,如果请求的对齐是基本的,则必须遵守该对齐;在理想情况下,如果编译器不能保证遵守扩展对齐,则编译器将生成错误消息。(不过,我不认为它有义务这么做;gcc和clang都会生成可执行文件,如果请求一个巨大的堆栈对齐,它们就会出错。)

两件事:a)对过度对齐类型的支持依赖于实现,并且b)非常迂腐地说,您要检查的只是转换后的值是否可整除。就语言而言,您没有“指针对齐”的概念“除了通过新的对齐语言功能。指针不是整数,它们只能转换为整数或从整数转换。请注意,我没有检查指针的对齐方式(即
&p
),我正在检查指针指向的对齐方式。是的,我同意,我正在检查指针转换为
long
的值,但是有没有更好的方法来查看我的对齐要求是否得到满足?是的,新的语言功能非常丰富,可能具有您所需要的功能,例如,在C++11之前,根本没有标准notion的对齐内存,这就是它被添加的原因。您以前必须使用特定于平台的方法。@KeithThompson:我没有将其打印为
长的
,我正在对其进行算术运算,以查看它是否是64的倍数。我删除了我的注释。但您可能应该转换为
uintptr\u t
(在
中声明)如果可用。有些实现中,
int*
大于
long
。我知道还有其他方法可以完成我想做的事情(例如,使用
std::aligned\u存储
std::align
),但我真的很想理解为什么我对
alignas
的使用不起作用。alignas操作简单的变量,而不是newgoody,我不知道-std::aligned存储看起来很不错&std::align正是我建议的,但更简洁,
std::aligned_存储
只是
alignas
的缩写o它也不能与
new
一起工作
std::align
是你想要的。实际上你只需要
(alignment-1)
字节的额外空间。我刚刚用g++4.8测试了这一点,没有任何东西会超过8字节(这是标准内存对齐方式).因此,我看不出该关键字有什么用处!在x86上,有一些寄存器要求内存对齐128字节(并且使用64字节作为OP)但不知何故,这完全没有用。太糟糕了。我甚至尝试过一个结构和一个类,结果都没有对齐。如果它只在已经正确对齐的类型上工作,那么就没有必要添加到语言中!@AlexisWilke:它是为堆栈分配(自动)对象设计的。(即使在那里,它也不能保证工作,但如果编译器不能保证对齐,它应该会提供一个编译时错误。)使用
new
分配的所有对象都具有相同的对齐方式(至少,使用默认的分配函数)。我在gcc 4.8/linux上试用过,使用alignas(8192)时效果很好.Ah…行得通。可惜新的也不行。我想我们还是要使用旧的memalign()函数。