如果在int之后出现char,为什么要添加填充?
例如,有一种结构
struct A { char a; int i; };
在这种情况下,我们有[1字节] +填充[3字节] + int [4字节] = 8。
现在让我们对上面的struct进行一些更新,
struct A { int i; char a; };
在这种情况下,char来自int并且不需要添加填充字节,这意味着sizeof(A)= 5字节,但在这种情况下我也得到8字节的结果。 为什么?
好的,这个案子怎么样
struct s { int b; double c; char a; };
根据下面给出的逻辑,有一个: size = b[4 bytes] + padding[4 bytes] + c[8] + a[1] + padding[7 bytes to align with double] = 24
,但执行后我得到16.这怎么可能?
在这种情况下,
char
来自int
并且不需要添加填充字节,这意味着sizeof(A) = 5
字节,但在这种情况下我也得到8
字节的结果。 为什么?
首先,您需要了解为什么需要填充?
维基说:
数据结构对齐是数据在计算机存储器中的排列和访问方式。 它由两个独立但相关的问题组成: 数据对齐和数据结构填充 。 当现代计算机读取或写入存储器地址时,它将以字大小的块(例如,32位系统上的4字节块)或更大的块来执行此操作。 数据对齐意味着将数据放入存储器偏移量等于字大小的某个倍数,这会因CPU处理内存的方式而提高系统性能 。 为了对齐数据,可能需要在最后一个数据结构的末尾和下一个数据结构的开始之间插入一些无意义的字节,即数据结构填充。
要使4
的大小倍数( int
对齐),第二个片段将填充3
个字节。 编译完成后,第二个片段将被填充以便正确对齐
struct A { int i; char a; char Padding[3]; // 3 bytes to make total size of the structure 8 bytes };
编辑:永远记住结构填充的两个黄金规则:
- 仅当结构成员后跟具有较大对齐要求的成员或在结构的末尾时才插入填充。
- 最后一个成员填充所需的字节数,以便结构的总大小应该是任何结构成员的最大对齐的倍数。
的情况下
struct s { int b; double c; char a; };
对齐将发生为
struct s { int b; // 4 bytes. b is followed by a member with larger alignment. char Padding1[4]; // 4 bytes of padding is needed double c; // 8 bytes char d; // 1 byte. Last member of struct. char Padding2[7]; // 7 bytes to make total size of the structure 24 bytes };
另请注意,通过更改结构中成员的顺序,可以更改维持对齐所需的填充量。 如果成员按降序对齐要求排序,则可以执行此操作。
struct s { double c; // 8 bytes int b; // 4 bytes char a; // 1 byte. Only last member will be padded to give structure of size 16 };
编译器必须在结构的末尾添加填充的原因是结构可以是数组的一部分,并且数组的每个元素必须正确对齐。
看来你的平台想要一个int对齐4个字节。
如果声明struct A
的数组:
struct A array[2];
然后, array[1]
的第一个int
成员也应该有4个字节的对齐。 所以编译器将你的struct A
填充为8个字节来完成它,而如果它没有添加任何填充并且sizeof(struct A)
是5个字节,则array[1]
将无法正确对齐。
(请记住,编译器不能在数组元素之间插入填充,填充必须是数组元素本身的一部分,因为sizeof array
必须与sizeof(struct A) * 2
在上面的情况中相同)
不仅struct
每个成员都必须是数据对齐的,而且struct
本身必须与struct
最大成员的大小对齐。 因此,填充添加到struct A
,使其大小应该是sizeof i
和sizeof a
较大者的倍数。
在这里查看C FAQ
如果要有一个结构数组,则数组中的所有元素必须具有相同的大小和对齐方式; 这意味着对于数组中的事物,大小必须是对齐的倍数。 只有当它没有直接合并到另一个数组中,而是用作另一个结构的一部分时,唯一一个大小不是对齐倍数的结构是有用的。 这种情况有时会发生,但不足以经常在语言设计中受到特别关注。