C语言结构体字节对齐

来源:互联网 发布:戴墨镜抽烟软件 编辑:程序博客网 时间:2024/05/19 17:07

结构体对齐方式有两种:

一:系统默认方式对齐

结构体的大小是结构体成员中占用字节最大的类型的整数倍。

     struct A

    {

         char ch;

         short sh;

         int      it;

         double d;

    };

sizeof(struct A) = 16; // sizeof(double)*2

    struct B

    {

       double d;

       int         it;

       short    sh;

       char     ch;

    };

sizeof(struct B) = 16; // sizeof(double)*2

   struct C

   {

       char        ch;

       short        sh;

      double      d;

      int               it;

   };

 sizeof(struct C) = 24; // sizeof(double)*3

    struct D

   {

       int     it;

       double d;

      char       ch;

      short     sh;

   };

   sizeof(struct D) = 24; // sizeof(double)*3

   struct E

   {

       struct F

       {

           int ia;

           char ca;

       }ff;

        char     ch;

   };

  sizeof(struct E) = 12; // struct F中最大数据类型int的字节整数倍。

接下来看看每个结构体的具体地址分配:

以结构体起始地址0x0000为例:
a、struct A
     &ch = 0x0000;  // 占2字节
     &sh = 0x0002;  // 占2字节
     &it   = 0x0004;  // 占4字节
     &d   = 0x0008;  // 占8字节
总共16字节,而且char和short之间有1个子节浪费,因为char本身只占1个字节。为什么char要分配两个字节呢?
   因为这是操作系统对内存读写的优化,每个内置类型的变量分配的地址一定是它本身占用字节的整数倍,在A结构体中short的地址应该从0x0001开始,但是0x0001不是short所占字节2的倍数,所以只能从0x0002开始分配内存。
b、struct B
    &d   = 0x0000;  // 占8字节
    &it   = 0x0008;  // 占4字节
    &sh = 0x000B;  // 占2字节
    &ch = 0x000D;  // 占1字节
总共16个字节,实际占用15个字节,末尾有一个字节浪费,因为结构体大小取决于double的整数倍。
   这种按照占用字节从大到小排列的方式不会造成数据之间有空余字节不会被使用现象,只有可能在末尾有空余字节。
c、struct C
   &ch = 0x0000;  // 占2字节
   &sh = 0x0002;  // 占6字节
   &d   = 0x0008;  // 占8字节
   &it   = 0x0010;  // 占4字节
总共24个字节,实际占用20个字节。char和short之间有1个字节空余,short和double之间有4个字节空余,末尾有4个字节空余。
d、struct D
    &it  = 0x0000;  // 占8字节
    &d  = 0x0008;  // 占8字节
    &ch = 0x0010;  // 占2字节
    &sh = 0x0012;  // 占2字节
总共24个字节,实际占用20个字节。int和double之间有4个空余字节,char与short之间有1个空余字节,末尾有4个空余字节。
e、struct E
   先解析struct F
       &ia = 0x0000;
       &ca= 0x0004;
   再解析struct E其他成员
      &ch = 0x0008;
总共12个字节,struct F占用8个字节,char ch占1个字节。struct F与char之间有3个空余字节。struct E末尾有3个空余字节。

二:#pragma pack(int)指定

#pragma pack(2)

sizeof(struct A) = 16;

sizeof(struct B) = 16;

sizeof(struct C) = 16;

sizeof(struct D) = 16;

sizeof(struct E) = 8;

最小字节分配为2。

#define PRINT_D(intValue)     printf(#intValue" is %d\n", (intValue))

#define OFFSET(struct,member)  ((char *)&(((struct *)0)->member) - (char *)0) // 查看结构体成员偏移量
PRINT_D(OFFSET(struct A,ch)); // 结构体A的ch成员的偏移量

推荐:http://www.cnblogs.com/motadou/archive/2009/01/17/1558438.html

原创粉丝点击