4

假设我们有一个数据包

struct Foo
{
    short size; // 2
    short type; // 2
    BYTE  data; // 1
    //1 byte padding not 3?
};

编译后它的长度为 6 个字节,并在结构的末尾添加了 1 个字节的填充。编译器不应该添加 3 个字节的填充以使结构大小为 8 个字节长吗?因为 32 位 cpu 喜欢访问 4 字节块中的数据

顺便说一句,#pragma pack(1) 它有 5 个字节长,正如预期的那样。

4

3 回答 3

8

您的structcontainsshort意味着这些可能需要在两个字节边界上对齐。如果您要创建没有填充的此结构的数组,则每个其他元素都会以短裤不正确对齐而告终,这可能会崩溃或变慢。

填充物的存在是为了安全和性能。在某些架构上,未对齐的读取会导致崩溃。因此编译器填充结构,使其成员在可除以它们的大小的地址上对齐。除此之外,编译器几乎没有理由添加额外的填充来将整个结构对齐在本机单词边界上。所以它只会在你的情况下添加一个字节。

尝试int在你的结构中有一个。这应该将填充更改为具有额外的 3 个字节的填充。int在两个字节之间也有in 将在字节之间进行填充。

编译器可以自由地对填充进行任何选择,除非您明确指定打包。不同的架构和不同的编译器会发生不同的事情。

于 2012-08-29T17:58:58.267 回答
4

您已经在 1 和 2 字节增量中访问内存,struct因此通过将结构对齐 6 字节与 8 字节,您不会进一步损害性能,因此编译器选择节省空间。如果您只是从不对结构对齐做出假设并让编译器做正确的事情,那么您在实践中就不必担心它。

于 2012-08-29T18:00:24.657 回答
2

因为 32 位 cpu 喜欢访问 4 字节块中的数据

不完全是。严格来说,当您访问的变量为字节长且变量地址为-bytes 对齐时,内存访问是对齐的(因为您在这里谈论对齐) 。 所以这并不意味着它是 4 字节对齐的。在您声明类型且数据范围为 2 个字节的情况下,可能是 2 个字节对齐。 NN
short

于 2012-08-29T18:03:52.517 回答