内存对齐与位段

12 篇文章 0 订阅
一.内存对齐
  许多实际的计算机系统对基本类型数据在内存中存放的位置有限制,它们会要求这些数据的首地址的值是某个数k(通常它为4或8)的倍数,这就是所谓的内存对齐,而这个k则被称为该数据类型的对齐模数(alignment modulus)。当一种类型S的对齐模数与另一种类型T的对齐模数的比值是大于1的整数,我们就称类型S的对齐要求比T强(严格),而称T比S弱(宽松)。
  这种强制的要求一来简化了处理器与内存之间传输系统的设计,二来可以提升读取数据的速度。比如这么一种处理器,它每次读写内存的时候都从某个8倍数的地址开始,一次读出或写入8个字节的数据,假如软件能保证double类型的数据都从8倍数地址开始,那么读或写一个double类型数据就只需要一次内存操作。否则,我们就可能需要两次内存操作才能完成这个动作,因为数据或许恰好横跨在两个符合对齐要求的8字节内存块上。某些处理器在数据不满足对齐要求的情况下可能会出错,但是Intel的IA32架构的处理器则不管数据是否对齐都能正确工作。不过Intel奉劝大家,如果想提升性能,那么所有的程序数据都应该尽可能地对齐。
  gcc默认情况下采用如下的对齐规则: 任何基本数据类型T的对齐模数就是T的大小,即sizeof(T)。比如对于double类型(8字节),就要求该类型数据的地址总是8的倍数,而char类型数据(1字节)则可以从任何一个地址开始。
  举例说明:
  struct foo {
    char c;
    int i;
    double d;
  };
  设想一下,sizeof(struct foo)应为多少?
  char类型对齐模数为1,所以先不用考虑;然后是int,对齐模数为4,也就是说,它必须从某个4倍数的地址开始,这样,前面的char型至少得加到4个字节(增加3个空的字节),现在,就是8个字节了,然后我们看double,对齐模数为8,好的,前面已经有8个字节,现在增加本身需要的8个字节空间,总共是16个,因此sizeof输出为16!
 
二.位段
  我们知道,一个字节=8位,在所有的简单数据类型中,要数char所占空间最小了吧:只有1字节,但是,某些情况下,我们可能只需要一位就可以表达,例如标记,问题是,我们没有对应的数据类型!
  例如:我们有多个作为标记的变量:
    unsigned int f1;
    unsigned int f2;
    unsigned int f3;
    unsigned int type;
    unsigned int index;
  算算看,总共需要多少存储空间:4*5=20字节,太浪费了一点吧!位段的概念由此引出:
  struct packed_struct
{
    unsigned int f1 :1;
    unsigned int f2 :1;
    unsigned int f3 :1;
    unsigned int type :4;
    unsigned int index :7;
};
表示:标志 f1, f2, f3 分别只需要 1 位。变量 type 只需要 4 位, 而变量index只需要7位,总共14位,不超过2个字节。
我们测一下:sizeof(struct packd_struct)为4,奇怪,为什么不是2或3而是4呢?
其实,哪怕是struct foo {unsigned int f1 :1},也会占用4个字节呢,与unsigned int相同。
总结一下:当位段出现在结构定义中时, 至少会占用等同于unsigned int类型的空间,当所有的位段之和超出,分配另一个unsigned int空间。
另外:unsigned char或者其他类型不必考虑。
 
三.何时位段会失效
例如:
struct bits
{
    unsigned int f1:1;
    int     word;
    unsigned int f3:1;
};
按照内存对齐的规则,位段声明会无效,上述sizeof(struct bits)为12!
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值