关于内存对齐#pragma pack( n )和__declspec( align(#) 的理解

     有问题欢迎指正

     关于内存对齐,是程序员指定将内存中数据放在“对齐”的位置上,这虽然造成了部分的内存空间的浪费,但可以提高计算机的速度。

     这个“对齐”的位置,就是指可以被一个数整除的地址,这个数叫做“对齐参数”,一般是1,2,4,8,16……具体这个参数的选取就要用到#pragma pack( n )和__declspec( align(#) 中的n,#以及数据本身所占字节的大小,比如char=1,int=4(32位)……

     放一句公式:

当一个变量或结构体同时受两者影响时,__declspec( align(#) 的优先级高。

     成员的地址决定于n及#,其要么是n的倍数,要么是#的倍数,要么是成员的大小的倍数,取最小。

        结构体最后的大小于#有关,其要么是#的倍数,要么是结构体中最大对其参数的倍数,取最大。


#pragma pack( 4 )

__declspec( align(16)struct A 

{

   char a;数据成员对齐规则,第一个成员放在offset=0的位置,a放在[0]字节

   short b; #=16>n=4>sizeof(short)=2,对齐参数选2,即b的地址必须可以被2整除,则[1]跳过,b放在[2,3]里

   int c; #=16>n=4=sizeof(int)=4,对齐参数选4,c的首地址若不跳过为4,可以被4整除,则c放在[4,5,6,7]

};

则这个结构体最后的大小即sizeof(A)=8? 公式第二句,结构体A中最大对齐参数是int c的4,#=16>4,则取16的倍数,结构体最后的大小为16.


特殊:如果有结构体B中嵌套一个结构体A,如果A受__declspec( align(#) 影响过,由于优先级高,则A的对齐参数为#,如果没有影响过,A结构体中的最大对齐参数与n选最小值作为对其参数。


#pragma pack( 4 )

struct B

{

             char a;同样,a放在[0]

             A b; 结构体A受__declspec( align(#) 影响,对齐参数为16,长度为16,则b放在[16,17…… 32]

             int c; c的对齐参数为4,放在[36,37,38,39]

};

现在的内存大小为40,能被4整除,所以sizeof(B)=40



如果不受__declspec( align(#) 影响

#pragma pack( 4 )

struct A

{

             char a; a放在[0]字节

             short b; b放在[2,3]里

             int c; c放在[4,5,6,7]

};

现在A的内存大小为8,可以被4整除,所以sizeof(A)=8,A的最大对齐参数是4

#pragma pack( 4 )

struct B

{

             char a;同样,a放在[0]

             A b;比较A的最大对齐参数4和n=4的最小值,则b的对齐参数也是4,放在[4,5…… 11]

             int c;对齐参数为4,放在[12,13,14,15]

};

现在的内存大小为16,能被4整除,所以sizeof(B)=16







你可能感兴趣的:(关于内存对齐#pragma pack( n )和__declspec( align(#) 的理解)