美文网首页
C++中的字节对齐

C++中的字节对齐

作者: 安然_fc00 | 来源:发表于2017-04-05 20:51 被阅读0次

    (字节对齐的实现细节和编译器有关)

    1. 基本概念

    字节对齐:计算机存储系统中以Byte为单位存储数据,不同数据类型所占的空间不同,如:整型(int)数据占4个字节,字符型(char)数据占一个字节,短整型(short)数据占两个字节,等等。计算机为了快速的读写数据,默认情况下将数据存放在某个地址的起始位置,如:整型数据(int)默认存储在地址能被4整除的起始位置,字符型数据(char)可以存放在任何地址位置(被1整除),短整型(short)数据存储在地址能被2整除的起始位置。这就是默认字节对齐方式。

    基本满足以下3个原则:

    • 结构体变量的首地址能够被其最宽基本类型成员的大小所整除;
    • 结构体每个成员相对于结构体首地址的偏移量(offset)都是成员大小的整数倍,如有需要编译器会在成员之间加上填充字节(internal padding);
    • 结构体的总大小为结构体最宽基本类型成员大小的整数倍,如有需要编译器会在最末一个成员之后加上填充字节(trailing padding)。

    2. 举例说明

    很显然默认对齐方式会浪费很多空间,例如如下结构:

    struct student
    {
        char name[5];
        int num;
        short score;
    }
    

    本来只用了11bytes(5+4+2)的空间,但是由于int型默认4字节对齐,存放在地址能被4整除的起始位置,即:如果name[5]从0开始存放,它占5bytes,而num则从第8(偏移量)个字节开始存放。所以sizeof(student)=16。于是中间空出几个字节闲置着。但这样便于计算机快速读写数据,是一种以空间换取时间的方式。其数据对齐如下图:
    |char|char|char|char|
    |char|----|----|----|
    |--------int--------|
    |--short--|----|----|

    如果我们将结构体中变量的顺序改变为:

    struct student
    {
        int num;
        char name[5];
        short score;
    }
    

    则,num从0开始存放,而name从第4(偏移量)个字节开始存放,连续5个字节,score从第10(偏移量)开始存放,故sizeof(student)=12。其数据对齐如下图:
    |--------int--------|
    |char|char|char|char|
    |char|----|--short--|

    如果我们将结构体中变量的顺序再次改为为:

    struct student
    {
        int num;
        short score;
        char name[5];
    }
    

    则,sizeof(student)=12。其数据对齐如下图:
    |--------int--------|
    |--short--|char|char|
    |char|char|char|----|

    3.#pragma pack()命令

    为了节省空间,我们可以在编码时通过#pragma pack()命令指定程序的对齐方式,括号中是对齐的字节数,若该命令括号中的内容为空,则为默认对齐方式。例如,对于上面第一个结构体,如果通过该命令手动设置对齐字节数如下:

    #pragma pack(2) //设置2字节对齐
    struct strdent
    {
       char name[5]; //本身1字节对齐,比2字节对齐小,按1字节对齐
       int num;          //本身4字节对齐,比2字节对齐大,按2字节对齐
       short score;    //本身也2字节对齐,仍然按2字节对齐
    }
    #pragma pack() //取消设置的字节对齐方式
    

    则,num从第6(偏移量)个字节开始存放,score从第10(偏移量)个字节开始存放,故sizeof(student)=12,其数据对齐如下图:
    |char|char|
    |char|char|
    |char|-----|
    |----int----|
    |----int----|
    |--short---|

    这样改变默认的字节对齐方式可以更充分地利用存储空间,但是这会降低计算机读写数据的速度,是一种以时间换取空间的方式。

    相关文章

      网友评论

          本文标题:C++中的字节对齐

          本文链接:https://www.haomeiwen.com/subject/kxsxattx.html