📜  结构的sizeof是否等于每个成员的sizeof之和?

📅  最后修改于: 2021-05-25 18:24:04             🧑  作者: Mango

先决条件: C语言中的sizeof运算符
结构的sizeof并不总是等于每个成员的sizeof之和。这是因为编译器添加了填充,以避免对齐问题。仅当结构成员后跟较大尺寸的成员或在结构末端时才添加填充。

不同的编译器可能具有不同的对齐方式约束,因为C标准指出结构的对齐方式完全取决于实现。

让我们看一下以下示例,以更好地理解:

  • 情况1:
    // C program to illustrate
    // size of struct
    #include 
      
    int main()
    {
      
        struct A {
      
            // sizeof(int) = 4
            int x;
            // Padding of 4 bytes
      
            // sizeof(double) = 8
            double z;
      
            // sizeof(short int) = 2
            short int y;
            // Padding of 6 bytes
        };
      
        printf("Size of struct: %ld", sizeof(struct A));
      
        return 0;
    }
    

    输出:

    Size of struct: 24
    


    红色部分表示为数据对齐而添加的填充,绿色部分表示结构成员。在这种情况下, x (int)后跟z (double),与x相比, z (double)的大小更大。因此,在x之后添加了填充。另外,最后需要填充以进行数据对齐。

  • 情况2:
    // C program to illustrate
    // size of struct
    #include 
      
    int main()
    {
      
        struct B {
            // sizeof(double) = 8
            double z;
      
            // sizeof(int) = 4
            int x;
      
            // sizeof(short int) = 2
            short int y;
            // Padding of 2 bytes
        };
      
        printf("Size of struct: %ld", sizeof(struct B));
      
        return 0;
    }
    

    输出:

    Size of struct: 16
    

    在这种情况下,结构的成员按其大小的降序排序。因此,仅在最后需要填充。

  • 情况3:
    // C program to illustrate
    // size of struct
    #include 
      
    int main()
    {
      
        struct C {
            // sizeof(double) = 8
            double z;
      
            // sizeof(short int) = 2
            short int y;
            // Padding of 2 bytes
      
            // sizeof(int) = 4
            int x;
        };
      
        printf("Size of struct: %ld", sizeof(struct C));
      
        return 0;
    }
    

    输出:

    Size of struct: 16
    


    在这种情况下, y (短整数)后跟x (整数),因此在y之后需要填充。在这种情况下,最后不需要填充以进行数据对齐。

C语言不允许编译器对结构成员进行重新排序以减少填充量。为了最小化填充量,必须以降序对struct成员进行排序(类似于情况2)。