那么,能不能既达到提高性能的目的,又能节约一点空间呢?有一点小技巧可以使用。
比如我们可以将上面的结构改成:
struct TestStruct2 {
char c1; char c2; short s; int i; };这样一来,每个成员都对齐在其自然边界上,从而避免了编译器自动对齐。
在这个例 子中,sizeof(TestStruct2)的值为8。这个技巧有一个重要的作用,尤其是这个结构作为API 的一部分提供给第三方开发使用的时候。
第三方开发者可能将编译器的默认对齐选项改变, 从而造成这个结构在你的发行的DLL 中使用某种对齐方式,而在第三方开发者哪里却使用 另外一种对齐方式。
这将会导致重大问题。
比如,TestStruct1 结构,我们的DLL 使用默认对齐选项,对齐为使用指令#pragma pack (),编译器将取消自定义字节对齐方式。
在#pragma pack (n)和#pragma pack ()之间的代码按n 个字节对齐。
但是,成员对齐有一个重要的条件,即每个成员按自己的方式对齐.也就是说虽然指定了 按n 字节对齐,但并不是所有的成员都是以n 字节对齐。
其对齐的规则是,每个成员按其类型 的对齐参数(通常是这个类型的大小)和指定对齐参数(这里是n 字节)中较小的一个对齐,
即:min( n, sizeof( item )) 。并且结构的长度必须为所用过的所有对齐参数的整数倍,不够就补空 字节。看如下例子: #pragma pack(8) struct TestStruct4 {
char a; long b; };TestStruct4 中,成员a 是1 字节默认按1 字节对齐,指定对齐参数为8,这两个值中取1,a 按1 字节对齐;
成员b 是4 个字节,默认是按4 字节对齐,这时就按4 字节对齐,所以 sizeof(TestStruct4)应该为8;
TestStruct5 中,c 和TestStruct4 中的a 一样,按1 字节对齐,而d 是个结构,它是8 个字节,它 按什么对齐呢?
对于结构来说,它的默认对齐方式就是它的所有成员使用的对齐参数中最大 的一个, TestStruct4 的就是4.
所以,成员d 就是按4 字节对齐.成员e 是8 个字节,它是默认按8
字节对齐,和指定的一样,所以它对到8 字节的边界上,这时,已经使用了12 个字节了,所以又添加了4 个字节的空,从第16 个字节开始放置成员e.这时,长度为24,已经可以被8(成员e 按8 字节对齐)整除.这样,
一共使用了24 个字节.内存布局如下(*表示空闲内存,1 表示使用内存。
单位为1byete): a b补充一下,对于数组,比如:char a[3];它的对齐方式和分别写3 个char 是一样的.
也就是说 它还是按1 个字节对齐.如果写: typedef char Array3[3];Array3 这种类型的对齐方式还是按1 个字节对齐,而不是按它的长度。
但是不论类型是什么,对齐的边界一定是1,2,4,8,16,32,64....中的一个。 另外,注意别的#pragma pack 的其他用法:
#pragma pack(push) //保存当前对其方式到packing stack #pragma pack(push,n) 等效于 #pragma pack(push)