C语言中的结构体数据存储-对齐规则

 (1)什么是字节对齐

  一个变量占用 个字节,则该变量的起始地址必须能够被 整除,即每个变量的起始存放地址 % n = 0, 
    对于结构体,这个 
取其成员种的数据类型占空间的值最大的那个。
    默认定义的指针,是CPU最大数据类型 如:对于32位CPU,char *p; 占4个字节
    而定义了数据的存储类型后,如:static char *p; 占1个字节
    即:A1存储地址addr1%A1对齐值=0,A2按顺序后延,如果下一个地址addr2%A2!=0就补空,后移存储地址addr3。若addr3%A2!=0,继续后移。
    同时,每个内存块为最大的对齐值N,不满的要补空。
    
    结构体中有结构体,把内中的结构体拆开看。 

  (2)为什么要字节对齐

  内存空间是按照字节来划分的,从理论上说对内存空间的访问可以从任何地址开始,但是在实际上不同架构的CPU为了提高访问内存的速度,就规定了对于某些类型的数据只能从特定的起始位置开始访问。这样就决定了各种数据类型只能按照相应的规则在内存空间中存放,而不能一个接一个的顺序排列。

  举个例子,比如有些平台访问内存地址都从偶数地址开始,对于一个int(假设32位系统),如果从偶数地址开始的地方存放,这样一个读周期就可以读出这个int数据,但是如果从奇数地址开始的地址存放,就需要两个读周期,并对两次读出的结果的高低字节进行拼凑才能得到这个int数据,这样明显降低了读取的效率。

  (3)如何进行字节对齐

  每个成员按其类型的对齐参数(通常是这个类型的大小)和指定对齐参数(不指定则取默认值)中较小的一个对齐,并且结构的长度必须为所用过的所有对齐参数的整数倍,不够就补空字节。

  这个规则有点苦涩,可以把这个规则分解一下,前半句的意思先获得对齐值后与指定对齐值进行比较,其中对齐值获得方式如下:

  1. 数据类型的自身对齐值为:对于char型数据,其自身对齐值为1,对于short型为2,对于int, long, float类型,其自身对齐值为4,对于 double 类型其自身对齐值为8,单位为字节。

  2.结构体自身对齐值:其成员中自身对齐值最大的那个值。

  其中指定对齐值获得方式如下:

  #pragma pack (value)时的指定对齐值value

  未指定则取默认值。

  后半句的意思是主要是针对于结构体的长度而言,对于结构体,它可能使用了多种数据类型,那么这句话翻译成对齐规则: 每个成员的起始地址 自身对齐值 = 0,如果不等于 则地址后移直到符合规则,前面的补空达到对齐值。

  换句话说,对于结构体而言,结构体在在内存的存放顺序用如下规则即可映射出来:

  ()单独的每个成员的起始地址 每个成员的自身对齐值 = 0,如果不等于 0 就后移,前面补空使得每个成员内存块为结构体中最大的对齐值。

  ()结构体的长度必须为结构体的自身对齐值的整数倍,不够就补空字节。
举例:
 typedef struct 
{
 char aa;
 short ab;
 char ac;
 long ad;
}A;
sizeof(A) 结果为: 12 内存位置为: $*$$  $***  $$$$ 注意:每个成员首地址必须为自身对齐值的整数倍。
 

typedef struct 
{
 long ba;
 short bb;
 long bc;
 char bd;
 short be;
}B;
sizeof(B)结果为:16  内存位置为:$$$$ $$** $$$$ $*$$   

typedef struct 
{
 char ca;
 char cb;
 short cc;
 char cd;
 short ce;
 A cf; 
 char cg;
 short ch;
 long ci;

}C;
sizeof(C)结果为:28  内存位置为:$$$$ $*$$ $*$$ $*** $$$$ $*$$ $$$$

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值