假设我们有一个数据包
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个字节,正如预期的那样。
答案 0 :(得分:7)
您的struct
包含short
,这意味着这些可能需要在双字节边界上对齐。如果你要创建没有填充的这个结构的数组,那么每个其他元素最终都会错误地对齐,这可能会崩溃或变慢。
填充存在是出于安全和性能的目的。在某些体系结构上,未对齐的读取会导致崩溃。因此编译器填充结构,以便它的成员对齐可按其大小分类的地址。除此之外,编译器几乎没有理由添加额外的填充,只是为了在原生字边界上对齐整个结构。因此,在您的情况下,它只会添加一个字节。
尝试在结构中使用int
。这应该更改填充以具有额外的3个字节的填充。在两个字节之间使用int
将在字节之间填充。
编译器可以自由地做任何关于填充的选择,除非你明确指定打包。不同的架构和不同的编译器会发生不同的事情。
答案 1 :(得分:3)
您已经在struct
中以1字节和2字节为增量访问内存,因此通过将结构与6字节对8进行对齐,您不会再损害性能,因此编译器会选择保存空间。如果你从不对结构对齐做出假设并让编译器做正确的事情,你就不必在实践中担心它。
答案 2 :(得分:1)
因为32位cpu喜欢以4字节块的形式访问数据
不完全是。严格来说,当您访问的变量长N
字节且变量地址为N
- 字节对齐时,内存访问是对齐(因为这里你谈的是对齐)。
所以它并不意味着它是4字节对齐的。可以是2字节对齐,就像您声明类型short
并且数据范围是2字节的情况一样。