C 如何正确计算结构的大小?

C 如何正确计算结构的大小?,c,structure,C,Structure,在Windows7上,64位MyStruct的大小是多少 typedef struct MyStruct_tag { char c; double d; int s; } MyStruct; 我的答覆是: 1 (Char) + 7 (Padding) + 8 (double) + 4 (int) = 20 bytes 但答案是24字节。发生了什么事 最后的int后面可能有4个字节的填充,

在Windows7上,64位MyStruct的大小是多少

    typedef struct MyStruct_tag
   {
       char        c;
       double      d;
       int         s;
    } MyStruct;
我的答覆是:

1 (Char) + 7 (Padding) + 8 (double) + 4 (int) = 20 bytes 

但答案是24字节。发生了什么事

最后的
int
后面可能有4个字节的填充,这样数组中下一个类似结构中的
double
的对齐将正确对齐


但最终,填充是由实现定义的。试图对它进行推理或预测是没有用的。编译器应该为您处理它。如果没有,请强烈重新考虑您正在做的事情。

最后的
int
后面可能会有4个字节的填充,这样数组中下一个类似结构中的
双精度
的对齐方式将正确对齐

但最终,填充是由实现定义的。试图对它进行推理或预测是没有用的。编译器应该为您处理它。如果没有,强烈地重新考虑你在做什么。

这是为了“对齐”。许多处理器无法访问2字节和4字节的数量(例如整数和长整数),如果它们以各种方式被塞满

假设您有以下结构:

struct  {
    char a[3];
    short int b;
    long int c;
    char d[3];
    };
现在,您可能认为应该可以像这样将此结构打包到内存中:

+-------+-------+-------+-------+
|           a           |   b   |
+-------+-------+-------+-------+
|   b   |           c           |
+-------+-------+-------+-------+
|   c   |           d           |
+-------+-------+-------+-------+
+-------+-------+-------+
|           a           |
+-------+-------+-------+
|       b       |
+-------+-------+-------+-------+
|               c               |
+-------+-------+-------+-------+
|           d           |
+-------+-------+-------+
+-------+-------+-------+-------+
|           a           | pad1  |
+-------+-------+-------+-------+
|       b       |     pad2      |
+-------+-------+-------+-------+
|               c               |
+-------+-------+-------+-------+
|           d           | pad3  |
+-------+-------+-------+-------+
但是,如果编译器按照以下方式进行排列,那么在处理器上要容易得多:

+-------+-------+-------+-------+
|           a           |   b   |
+-------+-------+-------+-------+
|   b   |           c           |
+-------+-------+-------+-------+
|   c   |           d           |
+-------+-------+-------+-------+
+-------+-------+-------+
|           a           |
+-------+-------+-------+
|       b       |
+-------+-------+-------+-------+
|               c               |
+-------+-------+-------+-------+
|           d           |
+-------+-------+-------+
+-------+-------+-------+-------+
|           a           | pad1  |
+-------+-------+-------+-------+
|       b       |     pad2      |
+-------+-------+-------+-------+
|               c               |
+-------+-------+-------+-------+
|           d           | pad3  |
+-------+-------+-------+-------+
packed”版本中,请注意,对于您和我来说,至少有一点难以看到b和c字段是如何环绕的?简而言之,这对处理器来说也很难。因此,大多数编译器将
pad''结构(好像有额外的不可见字段),如下所示:

+-------+-------+-------+-------+
|           a           |   b   |
+-------+-------+-------+-------+
|   b   |           c           |
+-------+-------+-------+-------+
|   c   |           d           |
+-------+-------+-------+-------+
+-------+-------+-------+
|           a           |
+-------+-------+-------+
|       b       |
+-------+-------+-------+-------+
|               c               |
+-------+-------+-------+-------+
|           d           |
+-------+-------+-------+
+-------+-------+-------+-------+
|           a           | pad1  |
+-------+-------+-------+-------+
|       b       |     pad2      |
+-------+-------+-------+-------+
|               c               |
+-------+-------+-------+-------+
|           d           | pad3  |
+-------+-------+-------+-------+
礼节-史蒂夫·萨米特

这是为了“对齐”。许多处理器无法访问2字节和4字节的数量(例如整数和长整数),如果它们以各种方式被塞满

假设您有以下结构:

struct  {
    char a[3];
    short int b;
    long int c;
    char d[3];
    };
现在,您可能认为应该可以像这样将此结构打包到内存中:

+-------+-------+-------+-------+
|           a           |   b   |
+-------+-------+-------+-------+
|   b   |           c           |
+-------+-------+-------+-------+
|   c   |           d           |
+-------+-------+-------+-------+
+-------+-------+-------+
|           a           |
+-------+-------+-------+
|       b       |
+-------+-------+-------+-------+
|               c               |
+-------+-------+-------+-------+
|           d           |
+-------+-------+-------+
+-------+-------+-------+-------+
|           a           | pad1  |
+-------+-------+-------+-------+
|       b       |     pad2      |
+-------+-------+-------+-------+
|               c               |
+-------+-------+-------+-------+
|           d           | pad3  |
+-------+-------+-------+-------+
但是,如果编译器按照以下方式进行排列,那么在处理器上要容易得多:

+-------+-------+-------+-------+
|           a           |   b   |
+-------+-------+-------+-------+
|   b   |           c           |
+-------+-------+-------+-------+
|   c   |           d           |
+-------+-------+-------+-------+
+-------+-------+-------+
|           a           |
+-------+-------+-------+
|       b       |
+-------+-------+-------+-------+
|               c               |
+-------+-------+-------+-------+
|           d           |
+-------+-------+-------+
+-------+-------+-------+-------+
|           a           | pad1  |
+-------+-------+-------+-------+
|       b       |     pad2      |
+-------+-------+-------+-------+
|               c               |
+-------+-------+-------+-------+
|           d           | pad3  |
+-------+-------+-------+-------+
packed”版本中,请注意,对于您和我来说,至少有一点难以看到b和c字段是如何环绕的?简而言之,这对处理器来说也很难。因此,大多数编译器将
pad''结构(好像有额外的不可见字段),如下所示:

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

礼貌-Steve Summit

4个填充位在最后一位成员之后。@haccks为什么?有什么好处吗?请阅读下面给出的答案和链接问题中的答案。在最后一个成员后面加4个空格。@haccks为什么?有什么好处吗?请阅读下面给出的答案和链接问题中的答案。您可以使用
\uuuuu attribute\uuuuuuuuu((打包))
指定不希望结构属性对齐(不是最佳做法)。您可以使用
\uuuuuu attribute\uuuuuu((打包))
指定不希望结构属性对齐(不是最佳实践)。在上面的映射中,您是否假设int为2字节?在上面的映射中,您是否假设int为2字节?