之前在对结构体或者类的大小问题上一直模棱两可,这两天看了一篇很透彻的博客加上自己的代码分析,真正的明白其中的道理,希望对大家也有所帮助。
保证三个原则:
1:数据成员对齐规则:结构(struct)(或联合(union))的数据成员,第一个数据成员放在offset为0的地方,以后每个数据成员存储的起始位置要从该成员大小或者成员的子成员大小(只要该成员有子成员,比如说是数组,结构体等)的整数倍开始(比如int在32位机为4字节,则要从4的整数倍地址开始存储。注意注意:该成员值得就是当前成员,不是第一个成员!!!
2:结构体作为成员:如果一个结构里有某些结构体成员,则结构体成员要从其内部最大元素大小的整数倍地址开始存储.(struct a里存有struct b,b里有char,int ,double等元素,那b应该从8的整数倍开始存储.)
3:收尾工作:结构体的总大小,也就是sizeof的结果,.必须是其内部最大成员的整数倍.不足的要补齐.
注意注意:比如如果补齐后发现是第24个字节,那说明一共有25个字节了,注意补齐。
打算的
代码实测:-表示对齐 =表示遵守第三条规则补齐
/************************************************************/ /* 内存对齐测试代码 */ /************************************************************/ #include <iostream> using namespace std; struct a { int a1; //0-3 int b1; //4-7 char c1;//8 short int d1;//10-11=12 }AA; struct b { int a1;//0-3 char b1;//4 int c1;//8-11 short int d1;//12-13=16 }BB; struct c { long long int a1; //0-7 int b1;//8-11 long long int c1;//16-23 char c2;//24=32 注意:是第24个字节 其实一共有25个了 补齐的话就是32 }CC; class d { char c0; // 0 double dd[3];// 8-31 char c; // 32=40 同上 }DD; typedef struct e { double weight; //0 - 7 int id; //8 - 11 float height; //12 - 15 char A; //16=24 同上 }EE; typedef struct f { int id; //0-3 double weight; //8-15 float height; //16-19=24 }FF; typedef struct g { char name[2]; //0-1 int id; //4-7 double score; //8-15 short grade; //16-17 FF b; //24-47=48 }GG; int main() { cout << sizeof(a) << endl; cout << sizeof(b) << endl; cout << sizeof(c) << endl; cout << sizeof(d) << endl; cout << sizeof(e) << endl; cout << sizeof(f) << endl; cout << sizeof(g) << endl; system("pause"); }运行结果:
对于paragma pack(PackValue)问题;只要保证前三个的前提下满足下列要求即可。
1.对于每个元素的对齐方式需要与PackValue做比较,求取最小值作为该元素的对齐方式。
2.对于最后整个结构的对齐方式,需要与PackValue做比较 ,求取该结构中最大字节的的元素与PackValue相比较得到最小值,该值的最小整倍数作为该结构的大小。
测试代码:
//不论类型是什么,对齐的边界一定是1,2,4,8,16,32,64....中的一个 #include <iostream> using namespace std; //其实就是需要算个min(当前变量的大小,n),按照较小的方式对齐就可以了,总的大小也是这样 #pragma pack(1) class Test1 { public: int a; //4 char b; //1 short c; //2 char d; //1 }; #pragma pack(2) class Test2 { public: int a; //0-3 char b; //4 short c; //6-7 char d; //8 };//9-10 #pragma pack(4) class Test4 { public: int a; //0-3 char b; //4 short c; //6-7 char d; //8 };//9-12 #pragma pack(8) class Test8 { public: int a; //0-3 char b; //4 short c; //6-7 char d; //8 };//9-12 #pragma pack(4) class TestB1 { public: int a; //0-3 char b; //min(1,4)= 1 4 short c; //min(2,4)= 2 6-7 char d; //min(1,4)=1 8 }; #pragma pack(2) class TestB2 { public: int a; //0-3 char b; //min(1,2)= 1 4 short c; //min(2,2)= 2 6-7 char d; //min(1,2)=1 8 }; int main() { int a1 = sizeof(Test1); //8 int a2 = sizeof(Test2); //a int a4 = sizeof(Test4); //c int a8 = sizeof(Test8); //c int b1 = sizeof(TestB1); //c int b2 = sizeof(TestB2); //a return 0; }
膜拜大神:http://blog.csdn.net/hairetz/article/details/4084088
