内存对齐问题

来源:互联网 发布:平民护肤品推荐 知乎 编辑:程序博客网 时间:2024/06/06 04:50

从网上看了几篇关于内存对齐的文章,以下是我的理解:


首先需要知道  可以通过以下命令设置对齐系数: #pragma pack(n) //n可以取1,2,4,8,16等,默认一般是8或16


先看一下内存对齐的规则:

1、  对于结构的各个成员,第一个成员位于偏移为0的位置,以后每个数据成员的偏移位置分两种情况:

                        #pragma pack(n) 中的n(对齐系数) 与 要定位的数据成员的自身长度 比较

        (1) n较小:  该成员偏移的起始位置(相对于第一个成员的偏移位置) 需要为n的整数倍

        (2) 该成员的自身长度较小:  该成员偏移的起始位置(相对于第一个成员的偏移位置) 需要为自身长度的整数倍


2、  在数据成员完成各自对齐之后,结构(或联合)本身也要进行对齐,对齐将按照#pragma pack指定的数值和结构(或联合)最大数据成员长度中,比较小的那个数值进行。最后结构体的大小应该为较小数值的整数倍.


了解了对齐规则,下面举几个例子:

struct st1 

{

    char a ;

    int  b ;

    short c ;

};

struct st2
{
    short c ;

    char  a ;

    int   b ;

;

此处假设 char占1字节, int占4字节 ,short占两个字节 


#pragma pack(4)时:

                   sizeof(st1) = 12             sizeof(st2) = 8 

首先分析结构体st1

         根据上述规则1 

               成员a占一个字节起始位置为0, 

               成员b占4字节, 与对齐系数n比较,大小相同. 所以成员b的起始位置应为4的整数倍由于a只占一个字节,所以                    需要补三个空字节, b的起始位置为4

               成员c占2个字节, 与对其系数n(4)比较, c长度较小, 成员c的起始位置为2(c所占字节)的整数倍 c的起始位置为                 8(a占1个字节,后面补了3个,b占4个, 所以前面所占位置为0-7 , 下一位置是8刚好是2的整数倍)                                         

              经规则1分析后 结构体内存存储为: a000 bbbb cc                 0代表补齐的内存

          根据上述规则2,

              整个结构体也需要对齐, st1中最大成员大小为4(int) 与n(4) 大小相同,所以结构体大小应为4的整数倍, 目前大                 小为10, 还需要在后面补齐两位. 

      

      st1在内存中最终的存储为:    a000 bbbb cc00    0位存储a , 1-3位补齐 , 4-7位存储b , 8-9位存储c , 10和11位补齐 


下面分析结构体st2

     规则1:

           c占2字节 起始位置为0, 0-1位存储c

           a占1字节  1<n(4) 所以a的起始位置为1(较小)的整数倍, a的起始位置为2,2位存储a

           b占4字节  4=n   b的起始位置为4的整数倍, b的起始位置为4,第3位补齐 4-7位存储b

     规则2:

           st2中成员最大为4, n也为4 , 所以结构体大小应为4的整数倍, 由于此时结构体大小刚好为8,所以不需要补位,

      综上st2的存储为   cca0 bbbb


再谈论一下#pragma pack(2)时:

         sizeof(st1) = 8             sizeof(st2) = 8 

 结构体st1:

      规则1:

             a占1字节 起始位置为0,0位存储a

             b占4字节 4>2(前面定义的对齐系数) , 所以b的起始位置应为2(4与2较小的)的整数倍, 1位补位,2-5位存储b 

             c占2字节 2=2 , c的起始位置为2的整数倍,6-7位存储c

          规则2:

             st1中成员最大为4 , n=2 , 4>2 ,所以结构体大小为2的整数倍

      

       n=2时结构体st1的存储为  a0bbbbcc


结构体st2:

      规则1:

             c占2字节 起始位置为 0,0-1位存储c

             a占1字节 1<2 a的起始位置为2,2位存储a

             b占 4字节 4>2 b的起始位置为2的整数倍,b的起始位置为4,3位补位,4-7位存储b

      规则2:

             结构体st2的最大成员大小为4, 4>2    结构体大小为2的整数倍

      综上结构体st2的存储为 cca0bbbb


其他情况都是根据那两条规则分析就可以了

0 0
原创粉丝点击