C-struct和union字节对齐深入学习

typedef struct test
{
    char num[10];
    double age;
};

1.基本概念

有四个概念需要理解:
A、数据类型自身的对齐值:
  指对该数据类型使用sizeof()操作符进行操作所得到的大小(单位,字节);

  对于[unsigned] char类型的数据,其自身对齐值为1字节;

  对于[unsigned] short类型的数据,其自身对齐值是2字节;

  对于[unsigned] int、float、等数据类型,其自身对齐值是4字节;

  对于double long 其自身对齐值为8;

在结构体test中,num是char类型,自身对齐值为1;age是doubule类型,自身对齐值为8

 

B、结构体、联合体、类的自身对齐值:
    指其所有基本类型的成员中自身对齐值最大的那个值;

    如果这些复合类型中有嵌套类型或复合类型的变量,则需要把这些嵌套的类型或复合类型的变量拆解成基本类型的成员之后再对齐;

在test结构体中,成员num的自身对齐值是1,double自身对齐值为8;结构体的自身对齐值为8

C、指定对齐值:
   指使用预处理指令#pragma pack(align_value)指定的对齐值align_value;


D、数据成员、结构体和类的有效对齐值:
          指其自身对齐值指定对齐值较小的那个值;
           其中, 有效对齐值是最终用来决定数据存放地址方式的值, 最重要;设定有效对齐值为N,就表示"对齐在N字节上,"也就是说,该数据的"存放起始地址%N = 0";

在结构体test中的,数据成员num的自身对齐值是1,指定对齐值是4,因此num的有效对齐值是1;
数据成员age的自身对齐值是8,指定对齐值是4,因此age的有效对齐值是4;也就是说age存放的起始地址必须是4的倍数的;
因此,0-9是存放num数组,10-11偏移,12-19是成员age的存放地址

结构体test的有效对齐值

 E、对齐后的结构体的总大小必须是其有效对齐值的整数倍

 //自身对齐值是1,指定对齐值是6,有效对齐值1

//f首地址0x0, 所在内存空间0x0-0x09

//自身对齐值是8,指定对齐值是6,有效对齐值6

 

//结构体自身对齐值是8,指定对齐值是6,此时结构体的有效对齐值是6;

2.union

和struct不同的是它不需要每个成员变量都对其。但要保证其内存要大于最大成员占用的字节长度,同时保证是有效对齐值的倍数

union test
{
    char name[10];
    double age;
}

 

如事例代码所示:char name[10]要占用10个字节,其自身对齐值为1,age要占用8个字节,其自身对齐值为8

因此union的自身对齐值为8,如果没有指定对齐值则有效对齐值取自身对齐值,因此其有效对齐值==自身有效值==8,所以Union的size既要满足>=10,又要满足是8的倍数,因此sizeof(test)=16

posted @ 2020-04-14 15:58  唯一诺  阅读(857)  评论(0编辑  收藏  举报