计算结构尺寸

calculating the size of structure

当我发现这个 struct ...

的大小时,我正在研究结构成员对齐和结构填充的概念
struct node{
  int b;
  char a;
 };

... 是 8 个字节(即它包含 3 个字节的填充),而此 struct ...

的大小
struct node{
  char a;
};

... 只有 1 个字节。为什么后者没有填充?

Data structure alignment.

描述的很精彩here

假设你有这样的结构:

struct  {
    char a[3];
    short int b;
    long int c;
    char d[3];
    };

现在,您可能认为应该可以像这样将此结构打包到内存中:

+-------+-------+-------+-------+
|           a           |   b   |
+-------+-------+-------+-------+
|   b   |           c           |
+-------+-------+-------+-------+
|   c   |           d           |
+-------+-------+-------+-------+

但如果编译器这样安排,处理器上会容易得多:

+-------+-------+-------+
|           a           |
+-------+-------+-------+
|       b       |
+-------+-------+-------+-------+
|               c               |
+-------+-------+-------+-------+
|           d           |
+-------+-------+-------+

在“'packed'”版本中,请注意,您和我至少有点难以看到 b 和 c 字段如何环绕?简而言之,处理器也很难。因此,大多数编译器将像这样“'pad'”结构(就像有额外的、不可见的字段一样):

+-------+-------+-------+-------+
|           a           | pad1  |
+-------+-------+-------+-------+
|       b       |     pad2      |
+-------+-------+-------+-------+
|               c               |
+-------+-------+-------+-------+
|           d           | pad3  |
+-------+-------+-------+-------+

此 post 解释了填充是如何完成的,而不是为什么要完成。请参考 hacks 的回答,了解为什么这样做。

记住这两条填充规则:

  1. 仅当结构成员后跟[=​​24=]一个具有更大对齐要求的成员或在end 的结构。
  2. 最后一个成员用所需的字节数填充,以便结构的总大小应该是任何结构成员的最大对齐的倍数。

第二个结构中的成员a后面没有任何成员或具有更大对齐的成员,它也是最大的对齐成员,这意味着--No Padding。

阅读此 以获得更详细的解释。

struct 成员的填充和对齐完全由编译器决定,除了第一个成员之前不能有任何填充。话虽如此,编译器通常会选择填充来实现对齐目的,因此,特别是

  1. 有可能同一结构的所有成员同时最优对齐,并且
  2. structs 的数组中,如果第一个数组元素的成员最佳对齐,那么所有其他元素的成员也将最佳对齐。

根据这些要求和类似要求,编译器通常会选择所需的最少填充量(理想情况下根本没有填充)。如果不同的成员类型有不同的对齐要求,那么上述考虑需要将 struct 表示填充到具有最严格对齐要求的成员大小的倍数。它们可能还需要在成员之间进行填充,具体取决于成员的类型及其顺序。