背景:前段时间遇到了朋友问我关于C++内存对齐的问题,想想自己也没有很好的理解其精髓,于是,上网搜索了点这方面的资料,理解以后写下这篇BLOG,希望对有同样的需求的朋友有所帮助。
举例: (我个人觉得还是用例子来解决引出问题,或许会明了些)
#include <iostream>
using namespace std;
union U{
double d;
char str[9];
};
struct Type{
double a;
int b;
char c;
union U u;
};
int main()
{
cout<<sizeof(Type)<<endl;
}
我在两个编译环境中测试了一下,结果如下:
(1) 编译环境:GCC 3.4.5 结果:32
(2) 编译环境:Visual Studio 2005 结果:32
现在我们分析一下这个例子中的内存分配 (很快你就能明白,这个结果是怎么得来的了 :-) )
无论是对union还是对struct,内存对齐的方法都是一样的。这里直接给出公式:
M = (在不做内存对齐的情况下,所需的内存大小);
Cs = (系统对齐系数);
N = (union或struct中,分量中所占内存最大的内存大小);
Ca = (总体对齐时用的系数)= Min(Cs,N);
最终内存大小 = (大于等于M)且(能够整除Ca)的最小自然数;
现在,我们根据上面提到的公式,计算一下例子中的内存大小:
struct Type中包含一个union U成员,所以,我们得知道这个union U的大小,先算出sizeof( union U )。
在union U中,M = MAX(8,9) = 9,CS = 8(经过上面的测试,可以知道两种编译器的默认对齐参数都是8),N = MAX(double,char[9]) = 9
所以,CA = MIN(CS,N) = 8; sizeof( union U ) = 16
再计算sizeof( struct Type ),M = 8+4+1+16 = 29,CS = 8,N = MAX(8,4,1,16) = 16
CA = MIN(8,16) = 8; sizeof( struct Type ) = 32(结果就这样出来啦!!很简单吧!)
设置系统默认对齐方式:
在文件首部添加这样的一句预处理命令:#pragma pack(n) 其中,n = 1,2,4,8,16
默认的情况下,#pragma pack(8)
其他的几种情况,可以自己试验一下。
推荐的参考:
一些常识可以参考:http://blog.csdn.net/cuibo1123/archive/2008/06/14/2547442.aspx 这位仁兄写的很详细!!不过,就是在计算sizeof()时,我没有按照他那种算法,因为我算过几个,都不太对。尤其是将他那种方法应用在我举的这个例子中,就出错了。朋友,你可以自己试一下。或许,你可以悟出更好的解决方法!!