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

内存对齐通过指定数据在内存中的位置提高计算机速度,通常涉及#pragma pack(n) 和 __declspec(align(#))。对齐参数n和#影响变量或结构体地址,取最小倍数。结构体大小根据最大对齐参数和#取最大倍数。嵌套结构体时,__declspec(align(#) 优先级高。
摘要由CSDN通过智能技术生成

     有问题欢迎指正

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

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

  

编译器的缺省字节对齐方式(自然对界)

在缺省情况下,C编译器为每一个变量或是数据单元按其自然对界条件分配空间。

在结构中,编译器为结构的每个成员按其自然对界(alignment)条件分配空间。各个成员按照它们被声明的顺序在内存中顺序存储(成员之间可能有插入的空字节),第一个成员的地址和整个结构的地址相同。

 

C编译器缺省的结构成员自然对界条件为“N字节对齐”,N即该成员数据类型的长度。如int型成员的自然对界条件为4字节对齐,而double类型的结构成员的自然对界条件为8字节对齐。若该成员的起始偏移不位于该成员的“默认自然对界条件”上,则在前一个节面后面添加适当个数的空字节。

 

C编译器缺省的结构整体的自然对界条件为:该结构所有成员中要求的最大自然对界条件。若结构体各成员长度之和不为“结构整体自然对界条件的整数倍,则在最后一个成员后填充空字节。

放一句公式:

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

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

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

C


#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







评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值