有问题欢迎指正
关于内存对齐,是程序员指定将内存中数据放在“对齐”的位置上,这虽然造成了部分的内存空间的浪费,但可以提高计算机的速度。
这个“对齐”的位置,就是指可以被一个数整除的地址,这个数叫做“对齐参数”,一般是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