大家都知道,C++空類的記憶體大小為1位元組,為了保證其對象擁有彼此獨立的記憶體位址。非空類的大小與類中非靜态成員變量和虛函數表的多少有關。
而值得注意的是,類中非靜态成員變量的大小與編譯器記憶體對齊的設定有關。
成員變量在類中的記憶體存儲并不一定是連續的。它是按照編譯器的設定,按照記憶體塊來存儲的,這個記憶體塊大小的取值,就是記憶體對齊。
一、引入問題。
#include<iostream>
using namespace std;
class test {
private :
char c='1';//1byte
int i;//4byte
short s=2;//2byte
};
int main(){
cout << sizeof(test) << endl;
return 0;
}
輸出:12
class test2 {
private:
int i;//4byte
char c = '1';//1byte
short s = 2;//2byte
};
int main(){
cout << sizeof(test2) << endl;
return 0;
}
輸出:8
我們可以看到。類test和test2的成員變量完全一樣,隻是定義順序不一樣,卻造成了2個類占用記憶體大小不一樣。而這就是編譯器記憶體對齊的緣故。
二、規則
1、第一個資料成員放在offset為0的地方,以後每個資料成員的對齊按照#pragma pack指定的數值和這個資料成員自身長度中,比較小的那個進行。
2、在資料成員完成各自對齊之後,類(結構或聯合)本身也要進行對齊,對齊将按照#pragma pack指定的數值和結構(或聯合)最大資料成員長度中,比較小的那個進行。
很明顯#pragma pack(n)作為一個預編譯指令用來設定多少個位元組對齊的。值得注意的是,n的預設數值是按照編譯器自身設定,一般為8,合法的數值分别是1、2、4、8、16。
即編譯器隻會按照1、2、4、8、16的方式分割記憶體。若n為其他值,是無效的。
三、問題分析
(1)對于類test的記憶體空間是這樣的:

記憶體配置設定過程:
1、char和編譯器預設的記憶體預設分割大小比較,char比較小,配置設定一個位元組給它。
2、int和編譯器預設的記憶體預設分割大小比較,int比較小,占4位元組。隻能空3個位元組,重新配置設定4個位元組。
3、short和編譯器預設的記憶體預設分割大小比較,short比較小,占2個位元組,配置設定2個位元組給它。
4、對齊結束類本身也要對齊,是以最後空餘的2個位元組也被test占用。
(2)對于類test2的記憶體空間是這樣的:
1、int和編譯器預設的記憶體預設分割大小比較,int比較小,占4位元組。配置設定4個位元組給int。
2、char和編譯器預設的記憶體預設分割大小比較,char比較小,配置設定一個位元組給它。
3、short和編譯器預設的記憶體預設分割大小比較,short比較小,此時前面的char配置設定完畢還餘下3個位元組,足夠short的2個位元組存儲,是以short緊挨着。配置設定2個位元組給short。
4、對齊結束類本身也要對齊,是以最後空餘的1個位元組也被test占用。
(3)使用#pragma pack(n)
#include<iostream>
using namespace std;
#pragma pack(1)//設定為 1 位元組對齊
class test {
private :
char c='1';//1byte
int i;//4byte
short s=2;//2byte
};
class test2 {
private:
int i;//4byte
char c = '1';//1byte
short s = 2;//2byte
};
int main(){
cout << sizeof(test) << endl;
cout << sizeof(test2) << endl;
return 0;
}
輸出:
可以看到,當我們把編譯器的記憶體分割大小設定為1後,類中所有的成員變量都緊密的連續分布。
至此,C++記憶體對齊總結已經差不多了。想要更多了解C++對象記憶體配置設定推薦陳浩的2篇文章:
http://blog.csdn.net/haoel/article/details/3081328
和http://blog.csdn.net/haoel/article/details/1948051
陳浩大神寫的太透徹了。
參考:http://www.cppblog.com/snailcong/archive/2009/03/16/76705.html
http://www.jb51.net/article/45406.htm
/**
* ————————如果覺得本博文還行,别忘了推薦一下哦,謝謝!
* 作者:錢書康
* 歡迎轉載,請保留此段聲明。
* 出處:http://www.cnblogs.com/zrtqsk/
*/