关于内存对齐

首先,从一个计算结构体字节大小的问题开始:

问题:在32位的编译系统中有如下结构体定义

   typedef struct

  {

       int A;

       char B;

  }T_S;

问,T_S的大小是多少字节?

 

答案:其实这个题目本身并不严谨,T_S的大小跟编译器以及编译选项是有关系的。

      

首先,在pc上一般编译器都会做内存对齐,这个主要有两方面的原因:

一、平台原因(移植原因),不是所有的硬件平台都能访问任意地址上的任意数据的;某些硬件平台只能在某些地址处取某些特定类型的数据,否则抛出硬件异常。

二、性能原因:数据结构(尤其是栈)应该尽可能地在自然边界上对齐。原因在于,为了访问未对齐的内存,处理器需要作两次内存访问;而对齐的内存访问仅需要一次访问。

 

对齐系数可以是1,2,4,8,16。一般来讲,对于32位的编译器默认采用4位对齐,但是也有一些嵌入式系统默认是不对齐的。可以通过预编译命令#pragma pack(n)改变默认对齐方式,其中n为对齐系数。另外,这个也和平台有关,在一些机器上int并不是32位的。

但是有一点需要注意的事,预编译命令#pragma pack(n)并不一定总是生效。就拿本题来说,A为4位,B为1位,如果我们指明要用8来对齐,则我们需要给B补上7位,如果是16对齐则要补15位,这是对空间的严重浪费^-^……编译器肯定不会容忍我们这样挥霍的,所以实际的对齐方式采用 [pack指定的对齐长度]和[struct中最长成员的长度]较小的一个,这样既满足了cpu的对齐要求又可以尽量减少空间的浪费。

 

对于本题,如果采用缺省对齐方式,则sizeof(T_s)等于8,其中A为4位,B为1位,补齐3位;

如果采用#pragma pack即不做对齐处理,则sizeof(T_s)等于5,其中A为4位,B为1位;

如果采用2对齐,则sizeof(T_s)等于6,其中A为4位,B为1位,补齐1位;

如果采用8对齐,则sizeof(T_s)等于8,其中A为4位,B为1位,补齐3位;

如果采用16对齐,则sizeof(T_s)等于8,其中A为4位,B为1位,补齐3位;


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值