结构体和共用体(内存对齐原则)

结构体:结构体(struct)是由一系列具有相同类型或不同类型的数据构成的数据集合。结构体变量所占内存的长度是各个成员的总和,每个成员分别占有自己的存储空间。

关键字:struct。

共用体:共用体(union)把几种不同数据类型的变量存放在同一块内存里,共用体中的变量共享同一块内存,后赋值的会覆盖重写前面内存空间。共用体变量所占内存的长度为定义时的最长成员的长度。

关键字:union。

struct 结构体名
{
    成员列表
};

union 共用体名
{
    成员列表
};

 

内存对齐的三条原则:

1:数据成员对齐规则:结构(struct)(或联合(union))的数据成员,第一个数据成员放在offset为0的地方,以后每个数据成员存储的起始位置要从该成员大小或者成员的子成员大小(只要该成员有子成员,比如说是数组,结构体等)的整数倍开始(比如int在32位机为4字节,则要从4的整数倍地址开始存储。
 
2:结构体作为成员:如果一个结构里有某些结构体成员,则结构体成员要从其内部最大元素大小的整数倍地址开始存储.(struct a里存有struct b,b里有char,int ,double等元素,那b应该从8的整数倍开始存储.)
 
3:收尾工作:结构体的总大小,也就是sizeof的结果,.必须是其内部最大成员的整数倍.不足的要补齐。

例子1:

struct data1
{
    double  d;            //8字节(基础数据存储字节大小,下同)
    int     i;            //4字节
    char    c1;           //1字节
    char    c2[9];
};

1.首先根据原则2判断成员中基本数据类型存储字节大小最大的为double类型,因此以8字节对齐。

2.从上往下,d为double分配8字节,i为int分配4字节,同时i后面的成员c1,c2为char类型,存储大小为1字节,编译器编译时认为没必要各自分配8字节,可以接在i后面共用一个8字节,所以i,c1,c2 = 4+1+(3+6)=14(这里char[9]为单个单个字节存储,所以可以拆分开),14字节不为8的倍数,根据原则3补齐为16字节。 

第一个8字节:第二个8字节:第三个8字节:
di+c1+c2[1]+c2[2]+c2[3]c2[4]+...+c2[9]

3.总的大小为 8+16=24,即sizeof(struct data1) 的值为 24。

例子2:

struct data2
{
    int     a;    //4(基础数据存储字节大小,下同)
    long    b;    //8(32位机器上为4)
    double  c;    //8
    float   d;    //4
    char    e;    //1
    short   f;    //2
}

1.首先判断成员中基本数据类型存储字节大小最大的为double类型,因此以8字节对齐。

2.从上往下,a为4字节对齐为8,b,c为8字节,d为4字节,e为1字节,f为2字节,d+e+f为7,所以对齐并公用一个8字节。

第一个8字节:第二个8字节:第三个8字节:第四个8字节:
abcd+e+f

例子3:

struct data4
{
    int         l;      //4(基础数据存储字节大小,下同)
    char        *s;     //8(32位为4,64位为8)
    short int   i;      //2
    char        c;      //1
    short int   a[5];   //2
}

1.最大为char*类型,以8字节对齐。

2.l为4补齐为8字节,s为8字节,i+c+a[1]+a[2]为7字节补齐为8字节,a[3]+a[4]+a[5]为6补齐8字节。

3.总字节为 8+8+8+8=32。

3.8+8+8+8=32,即sizeof(struct data2) 的值为 32。

例子4(共用体嵌套结构体):

struct inner
{
    char      c1;     //1(基础数据存储字节大小,下同)
    int       i;      //4 
    char      c2;     //1
};
union data3
{
    struct inner   t1;    //12(4+4+4,此处非基础数据存储元素,所以不能用来做内存对齐)
    doubel         d;     //8
    char           c;     //1
};

1.首先可以判断共同体内最大基础类型为double,对齐字节为8

2.共用体的内存大小由成员中最大的决定,除了结构体t1,最大的为d。

3.我们单独来看结构体t1的字节长度,根据内存对齐原则2结构体(共用体)内的结构体(共用体)成员对齐字节为其结构内部的最大元素,可以看出inner结构体内最大的基础类型为int,即对齐字节为4,c1补齐4字节.i为4字节,c2补齐4字节,总的为12字节。

4.所以共用体内最大元素t1占用内存为12字节,而对齐字节为8,所以将12补齐为16字节,即sizeof(union data3)的值为16。

 

PS:

本章内容例子参考《linux C编程实战》一书。

内存对齐原则转自https://www.cnblogs.com/linhaostudy/p/7715667.html博客。

如有侵权请联系我删除。

  • 10
    点赞
  • 47
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值