当我发现这个struct
的大小时,我正在经历结构成员对齐和结构填充概念的概念......
struct node{
int b;
char a;
};
...是8个字节(即它包含3个字节的填充),而这个struct
的大小......
struct node{
char a;
};
...只有1个字节。为什么后者没有填充?
答案 0 :(得分:7)
请记住这两个填充规则:
第二个结构中的成员a
后面没有任何具有更大对齐的成员或成员,它也是最大的对齐成员,这意味着 - 无填充。
请阅读此answer以获取更详细的说明。
答案 1 :(得分:2)
奇妙地描述here。
假设您有这种结构:
struct {
char a[3];
short int b;
long int c;
char d[3];
};
现在,您可能认为应该可以将此结构打包到内存中,如下所示:
+-------+-------+-------+-------+
| a | b |
+-------+-------+-------+-------+
| b | c |
+-------+-------+-------+-------+
| c | d |
+-------+-------+-------+-------+
但是如果编译器像这样安排它,它在处理器上要容易得多:
+-------+-------+-------+
| a |
+-------+-------+-------+
| b |
+-------+-------+-------+-------+
| c |
+-------+-------+-------+-------+
| d |
+-------+-------+-------+
在''包装''版本,注意你和我至少有点难以看到b和c字段是如何环绕的?简而言之,处理器也很难。因此,大多数编译器都会填充'''结构(好像有额外的,不可见的字段),如下所示:
+-------+-------+-------+-------+
| a | pad1 |
+-------+-------+-------+-------+
| b | pad2 |
+-------+-------+-------+-------+
| c |
+-------+-------+-------+-------+
| d | pad3 |
+-------+-------+-------+-------+
这篇文章解释了填充是如何完成的,而不是为什么要填充。请参考haccks'回答为什么要这样做。
答案 2 :(得分:1)
struct
成员的填充和对齐完全由编译器决定,除了在第一个成员之前不能有任何填充。话虽如此,编译器通常选择填充以用于对齐目的,特别是
structs
数组中,如果第一个数组元素的成员以最佳方式对齐,那么所有其他元素的成员就是如此。根据这些和类似的要求,编译器通常选择最少量的填充(理想情况下根本没有填充)。如果不同的成员类型具有不同的对齐要求,则上述考虑因素需要将struct
表示填充到具有最严格对齐要求的成员大小的倍数。它们可能还需要成员之间的填充,具体取决于成员的类型及其顺序。