对齐问题总结

字节对齐在笔试的时候经常出现,基本就是必考题目,这里把它详细的说明一下,希望以后做到类似的题目不要再出错了,这是综合了好多篇博客中对齐问题的总结篇!
1、字节对齐的原因:
字节对齐的原因在于CPU访问数据的效率问题,合理的利用自己对齐可以有效地节省存储空间。在32位的系统中使用4字节对齐能够使cpu的访问速度调高。如果一个int型数据放到对齐的位置,那么取出他可能只需要访问1次就可以,但是如果没有放到对齐的位置,那么就可能需要2,3次的才能取出整个数据。这样访问的效率就降低了。gcc中默认的都是4字节对齐。
2、在什么情况下是一次取出的呢?
当一个变量的内存地址正好位于他的长度的整数倍的时候!
3、编译器里面默认的对齐方式能不能更改呢?当然能
• 使用伪指令#pragma pack (n),C编译器将按照n个字节对齐。
• 使用伪指令#pragma pack (),取消自定义字节对齐方式。
还有下面的这种方式:
• __attribute((aligned (n))),让所作用的结构成员对齐在n字节自然边界上。如果结构中有成员的长度大于n,则按照最大成员的长度来对齐。
attribute ((packed)),取消结构在编译过程中的优化对齐,按照实际占用字节数进行对齐。
例如:
  struct stu{
   char sex;
   int length;
   char name[10];
  };
  struct stu my_stu;
在x86下,GCC默认按4字节对齐,它会在sex后面跟name后面分别填充三个和两个字节使length和整个结构体对齐!于是我们sizeof(my_stu)会得到长度为20,而不是15.
在一般的情况下:
  联合 :按其包含的长度最大的数据类型对齐。
结构体: 结构体中每个数据类型都要对齐而且结构体自己也要对齐。  
  使用attribute选项来设置,比如我们想让刚才的结构按一字节对齐,我们可以这样定义结构体
  struct stu{
   char sex;
   int length;
   char name[10];
  }attribute ((aligned (1)));
  struct stu my_stu;
  则sizeof(my_stu)可以得到大小为15。
  上面的定义等同于
  struct stu{
   char sex;
   int length;
   char name[10];
  }attribute ((packed));
  struct stu my_stu;
attribute((packed))得变量或者结构体成员使用最小的对齐方式,即对变量是一字节对齐,对域(field)是位对齐.
例2:

#pragma pack (2)
struct C
{
        char b;
        int a;
        short c;
};
#pragma pack ()

第一个变量b的自身对齐值为1,指定对齐值为2,所以,其有效对齐值为1,假设C从0x0000开始,那么b存放在0x0000,符合0x0000%1=0;第二个变量,自身对齐值为4,指定对齐值为2,所以有效对齐值为2,所以顺序存放在0x0002、0x0003、0x0004、0x0005四个连续字节中,符合0x0002%2=0。第三个变量c的自身对齐值为2,所以有效对齐值为2,顺序存放在0x0006、0x0007中,符合0x0006%2=0。所以从0x0000到0x00007共八字节存放的是C的变量。又C的自身对齐值为4,所以C的有效对齐值为2。又8%2=0,C只占用0x0000到0x0007的八个字节。所以sizeof(struct C)=8.
4、修改VC IDE的对齐方式:
在VC IDE中,可以这样修改:[Project]|[Settings],c/c++选项卡Category的Code Generation选项的Struct Member Alignment中修改,默认是8字节。
5、什么时候需要设置对齐
在设计不同CPU下的通信协议时,或者编写硬件驱动程序时寄存器的结构这两个地方都需要按一字节对齐。即使看起来本来就自然对齐的也要使其对齐,以免不同的编译器生成的代码不一样.

参考文档:
http://blog.csdn.net/21aspnet/article/details/6729724

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值