为什么这两个结构的大小不同?

时间:2011-02-25 05:30:14

标签: c struct

  

可能重复:
  Why isn't sizeof for a struct equal to the sum of sizeof of each member?

#include<stdio.h>

struct csie {
  char c;
  short s;
  int i;
  double e;
};  

struct ceis {
  char c;
  double e;
  int i;
  short s;
};

int main(void) {
  printf("csie = %d\n", sizeof(struct csie));
  printf("ceis = %d\n", sizeof(struct ceis));
  return 0;
}

输出是:

csie = 16

ceis = 24

5 个答案:

答案 0 :(得分:5)

alignment结构不同。

第一个结构:

struct csie {
  char c;  
  short s; // 3 bytes + 1 bytes of padding
  int i;   // 4 bytes
  double e; // 8 bytes
};  

struct ceis {
  char c; //1 byte + 7 bytes of padding
  double e; // 8 bytes
  int i; // 4 bytes
  short s; // 2 byte + 2 bytes of padding
};

在第一个结构中,char和short可以打包到同一个对齐块中,而在第二个结构中它们不能打包。

答案 1 :(得分:3)

这是非常依赖于体系结构的,并且您没有指定您所使用的系统类型。

然而,假设

  • char:1字节大小,无对齐
  • short:2字节大小,与2字节边界对齐
  • int:4字节大小,与4字节边界对齐
  • double:8字节大小,对齐到8字节边界

这很容易解释。

+------+    +------+
| char |  0 | char |
+------+    +------+
|      |  1 |      |
+------+    |      |
|      |  2 |      |
| short|    |      |
|      |  3 |      |
+------+    |      |
|      |  4 |      |
|      |    |      |
|      |  5 |      |
|  int |    |      |
|      |  6 |      |
|      |    |      |
|      |  7 |      |
+------+    +------+
|      |  8 |      |
|      |    |      |
|      |  9 |      |
|      |    |      |
|      | 10 |      |
|      |    |      |
|      | 11 |      |
|double|    |double|
|      | 12 |      |
|      |    |      |
|      | 13 |      |
|      |    |      |
|      | 14 |      |
|      |    |      |
|      | 15 |      |
+------+    +------+
         16 |      |
            |      |
         17 |      |
            |  int |
         18 |      |
            |      |
         19 |      |
            +------+
         20 |      |
            | short|
         21 |      |
            +------+
         22 |      |
            |      |
         23 |      |
            +------+

结构中有空的空间(称为填充),因为某些数据结构必须落在某些字节边界上。

请注意,整个结构必须与8字节边界对齐,以保持其成员的对齐;这就是为什么在第二个版本的尾部有额外的填充。

答案 2 :(得分:0)

它几乎肯定与对齐有关。不同的类型必须在内存中以不同的方式对齐,并且由于一个结构的元素的顺序与另一个结构的顺序不同,因此它们的排列方式不同。

这些差异如何在架构,操作系统和编译器之间发生很大差异。有关更具体的信息,请参阅the Wikipedia article和您的OS /编译器手册。

答案 3 :(得分:0)

许多机器要求数据类型与内存中的适当边界对齐。在您的情况下,可能是CPU需要将双精度对齐到8字节边界。

因此第一个结构中的char,short和int只需要填充1个字节,而在第二个结构中,只需要在char和double之间填充7个字节的填充。

答案 4 :(得分:0)

您使用的是64位计算机。因此,所有分配都在64位(8字节)块中。 double是8个字节,必须在自己的块中。其他字段可以共享块。

显然,编译器不够复杂,无法在结构的第二个版本中节省空间:

  • 它为char分配第一个块,从而浪费了大部分块。
  • 为double分配第二个块。
  • 它为int和short分配第三个块。