C++記憶體對齊總結【轉載】
大家都知道,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/
*/