我正在寻找一本关于C ++中内存对齐的好(全面)文档,典型方法,编译器之间的差异以及常见的陷阱。只是为了检查我对这个主题的理解是否正确并学习新的东西。
这个问题的灵感来自于我对另一个问题的回答,其中我使用了以下构造:
char const buf[1000] = ...;
unsigned int i = *reinterpret_cast<unsigned int*>(buf + shift); // shift can be anything
它被批评为不符合内存对齐规则。你可以解释为什么这种方法从内存对齐的角度来看是有缺陷的?一个不起作用的例子将受到高度赞赏。我知道这通常是一种糟糕的方法,但我经常在网络协议实现中使用它,所以它比理论问题更实际。
另外请不要在这里提到严格别名,这是另一个问题。
答案 0 :(得分:6)
char
的非堆分配数组对其对齐没有特定要求。所以你的1000个字符的缓冲区可能是奇数偏移量。尝试从该偏移量中读取int
(重新解释为明显的int指针),如果编译器不将其拆分为单独的读取+位掩码操作,则会导致性能不佳甚至某些硬件上的总线错误。
保证堆分配的char
数组可以适当地对齐以存储任何对象类型,因此这始终是一个选项。
对于非基于堆的存储,请使用boost::aligned_storage
,以确保空间正确对齐以供一般使用。
答案 1 :(得分:3)
您可以在wikipedia找到相关概述。 更详细地介绍IBM站点:Data alignment: Straighten up and fly right
答案 2 :(得分:0)
想象一下地址必须是16字节对齐的情况,例如PS3。 然后想象一下班次== 1。 这肯定是一个非16字节对齐的指针,在这台机器上不起作用。