9

我正在寻找一个关于 C++ 中的内存对齐、典型方法、编译器之间的差异和常见陷阱的好的(全面的)文档。只是为了检查我对主题的理解是否正确并学习新东西。

这个问题的灵感来自我对另一个问题的回答,其中我使用了以下构造:

char const buf[1000] = ...;
unsigned int i = *reinterpret_cast<unsigned int*>(buf + shift); // shift can be anything

它被批评为不符合内存对齐规则。您能否解释一下为什么从内存对齐的角度来看这种方法存在缺陷?一个不起作用的例子将受到高度赞赏。我知道这通常是一种不好的方法,但我经常在网络协议实现中使用它,所以它更像是一个实际问题而不是理论问题。

另外请不要在这里提及严格混叠,这是另一个问题。

4

3 回答 3

6

非堆分配数组char对其对齐没有特定要求。所以你的一千个字符的缓冲区可能在一个奇怪的偏移量上。如果编译器不将其拆分为单独的读取 + 位掩码操作,则尝试int从该偏移量读取一个(明显地重新解释为 int 指针)会导致性能不佳甚至在某些硬件上出现总线错误。

堆分配的数组char保证可以适当地对齐以存储任何对象类型,因此这始终是一种选择。

对于基于非堆的存储,使用boost::aligned_storage确保空间正确对齐以供一般使用。

于 2011-09-06T13:37:56.177 回答
3

您可以在wikipedia上找到概述。在 IBM 网站上进行更深入的了解:数据对齐:直起身子并正确飞行

于 2011-09-06T13:42:03.563 回答
0

想象一下地址必须是 16 字节对齐的情况,例如 PS3。然后想象 shift == 1。这肯定是一个非 16 字节对齐的指针,在这台机器上不起作用。

于 2011-09-06T13:43:51.570 回答