記憶體位址的對齊主要考慮三個因素:
1:對於每個成員的起始地址是他本身所佔的整數倍
2:整個所佔的記憶體是成員中占的地址記憶體最多的整數倍
3:有#pragma pack(int)進行設定,如果結構體某成員的sizeof大於你設定的,則按你的設定來對齊
注意:每次用#pragma pack(int)進行設定後,要用#pragma pack()對其結束,免得造成錯誤
#include<iostream><br />using namespace std;</p><p>struct A<br />{<br />int a; //0 1 2 3<br />char b; //4 *<br />short c; //6 7<br />};</p><p>struct B<br />{<br />char a; //0 * * *<br />int b; //4 5 6 7<br />short c; //8 9 * *<br />};</p><p>#pragma pack(2)<br />struct C<br />{<br />char a; //0 *<br />int b; //2 3 4 5<br />short c; //6 7<br />};<br />#pragma pack()</p><p>#pragma pack(1)<br />struct D<br />{<br />char a; //0<br />int b; //1 2 3 4<br />short c; //5 6<br />};<br />#pragma pack()</p><p>int main()<br />{<br />cout<<"sizeof(A) = "<<sizeof(A)<<endl;<br />cout<<"sizeof(B) = "<<sizeof(B)<<endl;<br />cout<<"sizeof(C) = "<<sizeof(C)<<endl;<br />cout<<"sizeof(D) = "<<sizeof(D)<<endl;</p><p>return 0;<br />}
sizeof(A) = 8<br />sizeof(B) = 12<br />sizeof(C) = 8<br />sizeof(D) = 7<br />Press any key to continue
注意下面我對#pragma pack() 用法的理解,他不僅對每個成員的起始地址起作用,對整個的也起作用。請看下面的測試程式
#include<iostream><br />using namespace std;</p><p>#pragma pack(4)<br />struct AA<br />{<br />char a; // 0 * * * * * * *<br />double b; //4 5 6 7 8 9 10 11<br />int c; //12 13 * *<br />};//16<br />#pragma pack()</p><p>#pragma pack(2)<br />struct AAA<br />{<br />char a; // 0 *<br />double b; //2 3 4 5 6 7 8 9 起始地址也只要是2的倍數,不是8的倍數<br />int c; //10 11 * *<br />};//14 只要保證是2的倍數,不是最大double的8的倍數<br />#pragma pack()</p><p>int main()<br />{<br /> cout<<"sizeof(AA) = "<<sizeof(AA)<<endl;<br /> cout<<"sizeof(AAA) = "<<sizeof(AAA)<<endl;<br /> return 0;<br />}
sizeof(A) = 24<br />sizeof(AA) = 40<br />sizeof(A2) = 20<br />sizeof(AA2) = 28<br />Press any key to continue
下面接受有結構體嵌套的時候:
對於整個結構體作為成員函數時,他的起始地址不是以該結構體整體作為標準,而是以其內的成員為標準
#include<iostream><br />using namespace std;</p><p>struct A<br />{<br />int a; //0 1 2 3<br />char b; //4 * * *<br />double c; //8 9 10 11 12 13 14 15<br />short d; //16 17 * * * * * *<br />};//24</p><p>struct AA<br />{<br />char a; //0 * * * * * * *<br />A b; //8 .. 31<br />int c; //32 33 34 35 * * * *<br />};</p><p>#pragma pack(4)<br />struct A2<br />{<br />int a; //0 1 2 3<br />char b; //4 * * *<br />double c; //8 9 10 11 12 13 14 15<br />short d; //16 17 * *<br />};//20<br />#pragma pack()</p><p>struct AA2<br />{<br />char a; //0 * * *<br />A2 b; //4 .. 23<br />int c; //24 25 26 27<br />};</p><p>int main()<br />{</p><p>cout<<"sizeof(A) = "<<sizeof(A)<<endl;<br />cout<<"sizeof(AA) = "<<sizeof(AA)<<endl;<br />cout<<"sizeof(A2) = "<<sizeof(A2)<<endl;<br />cout<<"sizeof(AA2) = "<<sizeof(AA2)<<endl;<br />return 0;<br />}
sizeof(A) = 24<br />sizeof(AA) = 16<br />sizeof(AAA) = 14<br />Press any key to continue
最後注意:static成員和函數其實是類層次的,不在對象中分配空間,而成員函數其實是被編譯為全域函數了,所以也不在對象中。
#include<iostream><br />using namespace std;</p><p>struct empty{}; // 1<br />struct constAndStatic<br />{<br /> const int i; //0 1 2 3 * * * *<br /> const double d; //8 9 10 11 12 13 14 15<br />static char c;<br /> static void TestStatic(){}<br /> void TestNoStatic(){}<br />}; // 16</p><p>int main()<br />{</p><p> cout<<"sizeof(empty) = "<<sizeof(empty)<<endl;<br /> cout<<"sizeof(constAndStatic) = "<<sizeof(constAndStatic)<<endl;</p><p>return 0;<br />}
sizeof(empty) = 1<br />sizeof(constAndStatic) = 16<br />Press any key to continue