字节对齐(Alignment)

来源:互联网 发布:儿童美术教师培训网络 编辑:程序博客网 时间:2024/05/19 03:25
  平常说的字节对齐主要是指按地址对齐,也就是数据的存取地址具有某种相同的特性,即能被某个数据长度值整除。例如,32位(4字节)长的数据的存取地址能被4整除。


  字节对齐主要是硬件平台的要求,因为对齐的话硬件上实现起来比较简单。反过来说,如果不对齐,那么就有可能因为硬件不支持该操作而触发异常,或者硬件支持,但是实现起来相对比较复杂,导致存取效率不高。譬如32位平台,读取int型数据,如果硬件平台每次读都从偶地址开始,那么要是这个int型数据存放在奇地址开始的地方,就需要读取两次,并且还需要对两次读取结果进行拼装,这样一来肯定慢多了。


  一般情况下,也不是特别需要注意字节对齐问题,因为编译器把相关的问题自动处理了。比较明显的是C中的结构体。像结构体

    struct MyType {
        int a;
        short b;
        char c;
    };

  在32位平台上,sizeof(struct MyType)值为8,而不是sizeof(a) + sizeof(b) + sizeof(c) = 7。其原因就是编译器为了达到字节对齐的目的,往结构体中加入了隐藏填充字段。该结构体等价于
    struct MyType {
        int a;
        short b;
        char c;
        char padding; //编译器添加
    };


  字节对齐与数据类型有关。像32位平台上, charshortint,long,floatdoublepointer结构体,类自身对齐值12484成员中自身对齐值最大的那个值

(这里说的对齐值就是地址能被该长度整除)

  另外,也可以手工使用#pragma pack (value)指令来设置一个指定对齐值。实际生效的对齐值将是自身对齐值和指定对齐值中小的那个值。


  字节对齐相关的也主要是需要意识到这个概念,在设计结构时可以注意节省空间,同时尽力避免编译器自动填充引发的隐患。比较简单的方式就是可以像网络协议一样,画个表格,然后把各字段填进去。这样结构一目了然,有多少填充/保留字段也很明确(对于这些字段也该主动赋予名字,而不是让编译器来完成)。一般是合理安排,使此类字段尽可能的少或者日后有扩展意义。