最近任务完成后,又重新捡起一些基础书籍看看,弥补一下自己的基础知识,就遇到一个问题,这里问问明白人。
看到字节对齐的时候,就自己写几个测试,结果大跌眼镜:struct test1 {
           char text[2];
           long number1;
           long long number2;
};
int nsize = sizeof(test1);结构体test1的大小很好理解,根据字节对齐的理论,针对char,系统自动填充2个字节,long大小是4,long long的大小是8,所以test1的大小为16,运行结果跟我设想一致。但是接下来的我就不理解了struct test2 {
           char text[5];
           long number1;
           long long number2;
};
int nsize = sizeof(test1);
struct test3 {
           char text[2];
           long long number2;
           long number1;
};
int nsize = sizeof(test1);结构体test2和test3的大小都是24,请问,为什么两个结构体大小都为24?

解决方案 »

  1.   

    元素的起始地址是sizeof(元素类型)的整数倍,结构体大小是最大元素的整数倍。
    所以
    test2 
    text 5字节, 空3字节
    number1  4字节,空4字节
    number2 8字节test3 
    text 2字节,空6字节
    number2 8字节
    number1  4字节,空4字节
      

  2.   

    那按照这个说,结构test1也应该是24,那为什么是16,就这点不懂
      

  3.   

    那按照这个说,结构test1也应该是24,那为什么是16,就这点不懂
    test1 就是你说的啊。
      

  4.   

    test1 里 2 + 4  = 6  再补2个字节就对齐到8字节,所以是 8 + 8 = 16
    test2 里 5 + 4 = 9  大于8字节,只能分别对齐到8字节,所以是 8 + 8 + 8 = 24
      

  5.   

    仅供参考:#include <stdio.h>
    #define field_offset(s,f) (int)(&(((struct s *)(0))->f))
    struct AD  { int a; char b[13]; double c;};
    #pragma pack(push)
    #pragma pack(1)
    struct A1  { int a; char b[13]; double c;};
    #pragma pack(2)
    struct A2  { int a; char b[13]; double c;};
    #pragma pack(4)
    struct A4  { int a; char b[13]; double c;};
    #pragma pack(8)
    struct A8  { int a; char b[13]; double c;};
    #pragma pack(16)
    struct A16 { int a; char b[13]; double c;};
    #pragma pack(pop)
    int main() {
        printf("AD.a %d\n",field_offset(AD,a));
        printf("AD.b %d\n",field_offset(AD,b));
        printf("AD.c %d\n",field_offset(AD,c));
        printf("AD sizeof %d\n", sizeof(AD));
        printf("\n");
        printf("A1.a %d\n",field_offset(A1,a));
        printf("A1.b %d\n",field_offset(A1,b));
        printf("A1.c %d\n",field_offset(A1,c));
        printf("A1 sizeof %d\n", sizeof(A1));
        printf("\n");
        printf("A2.a %d\n",field_offset(A2,a));
        printf("A2.b %d\n",field_offset(A2,b));
        printf("A2.c %d\n",field_offset(A2,c));
        printf("A2 sizeof %d\n", sizeof(A2));
        printf("\n");
        printf("A4.a %d\n",field_offset(A4,a));
        printf("A4.b %d\n",field_offset(A4,b));
        printf("A4.c %d\n",field_offset(A4,c));
        printf("A4 sizeof %d\n", sizeof(A4));
        printf("\n");
        printf("A8.a %d\n",field_offset(A8,a));
        printf("A8.b %d\n",field_offset(A8,b));
        printf("A8.c %d\n",field_offset(A8,c));
        printf("A8 sizeof %d\n", sizeof(A8));
        printf("\n");
        printf("A16.a %d\n",field_offset(A16,a));
        printf("A16.b %d\n",field_offset(A16,b));
        printf("A16.c %d\n",field_offset(A16,c));
        printf("A16 sizeof %d\n", sizeof(A16));
        printf("\n");
        return 0;
    }
    //AD.a 0
    //AD.b 4
    //AD.c 24
    //AD sizeof 32
    //
    //A1.a 0
    //A1.b 4
    //A1.c 17
    //A1 sizeof 25
    //
    //A2.a 0
    //A2.b 4
    //A2.c 18
    //A2 sizeof 26
    //
    //A4.a 0
    //A4.b 4
    //A4.c 20
    //A4 sizeof 28
    //
    //A8.a 0
    //A8.b 4
    //A8.c 24
    //A8 sizeof 32
    //
    //A16.a 0
    //A16.b 4
    //A16.c 24
    //A16 sizeof 32
    //
    //
      

  6.   

    size = 最后一个元素的偏移地址+当前长度+对齐长度
      

  7.   

    VC编译器默认的的结构体对齐是Z8(8字节)可以用 #pragma pack 定义结构体对齐字节数
    #pragma pack(push, 1) //1字节对齐#pragma pack(pop)
      

  8.   

    struct test2 {
               char text[5];
               long number1;
               long long number2;
    };
    text占0,1,2,3,4五个字节,下一个成员就从5开始,但是起始地址值需要是长度long number1的整数倍,所以需填充5~7三个字节,所以从8开始,number1就占了8~11这四个字节,下一个long long number2就从12开始,但是起始地址值需要是长度的整数倍,所以需填充12_15这四个字节,所以最后一个成员number2就从16开始,即16~23这八个字节的长度,因此是24字节的大小,24是最大成员number2的长度的整数倍,所以最后结构体的sizeof就是24.struct test3 {
               char text[2];
               long long number2;
               long number1;
    };
    text占0,1两个字节,下一个从2开始,但是起始地址值需要是长度long long number2的整数倍,所以需填充2~7六个字节,所以从8开始,number2就占了8~15这八个字节,下一个long number1就从16开始,即16~19这四个字节的长度,因此是20字节的大小。但是最终结构体的sizeof值必须是最大成员number2长度整数倍,所以最后需要填充20~23四个字节,即最后结构体的sizeof就是24.