有关C/C++数据边界对齐的基本知识我不再描述了,下面我根据我的一些经验简单描述一下数据边界对齐的注意事项。
1、数据对齐的使用
当初弄明白数据边界对齐的原理,并没有思考具体怎么使用,而是为了应付面试。
当建立一个struct或者class,必须考虑其成员变量的数据对齐,来尽可能减少空间的浪费,把占用空间小的元素放在struct/class的前面。例子:
struct align { double b; char c; int a; };
以上这个结构体,由于 double b 排在前面,所以该结构体以double作为数据对齐的方式,double为8个字节的空间,则一下c与a也将会分别占用8个字节的空间,则:
sizeof(align)
后则会占用3*8=24个字节的空间。再来看下面这个结构体:
struct align { char c; int a; double b; };
c排在前面,采用1字节对齐,接着到a,则采用4字节对齐,到此,align占用了8个字节:c:4个字节,a:4个字节。然后到b,double型采用8字节对齐,由于a+c的空间已经是8字节了,所以c+a+b所占用的空间可以等价于 4+4+8 = 16 个字节,直接比上一个结构体节省了8个字节。
用法:把struct/class里的成员变量的大小排个序,按照从小到大的顺序写入结构体内,则能尽可能节省内存空间。
特殊情况:
有的class/struct内的成员变量具有上下文关系,我们可以把相关的成员存储在一起,以便于理解和维护,建议不按照上面的用法来节省内存空间。如:
struct product { int cdrom_amount; double cdrom_unit_price; int phone_amount; double phone_unit_price; };
这个结构体,建议按照这种成员排列序列吧,别动手术了。
2、强制数据对齐
应该知道 #pragma pack(2) 的使用:
#pragma pack(2) struct align { char c; int a; double b; }; #pragma pack()
以上这个结构体强制采用2对齐的方式,则该结构体占用的空间为 2+4+8 = 14 。对某个结构体使用强制数据对齐之后,注意恢复数据对齐的方式,即在结构体的后记得加上:
#pragma pack()
还有要注意的是不要滥用这个功能,可能会破坏内存的堆栈,或者强制转化的时候发生一些不可预料的情况。慎用。
以上是我总结的,由于表达能力有些欠缺,可能也有我一些理解错误或者理解不透彻的地方,希望大家能指出,望本文能抛砖引玉。