C++笔记——有关内存对齐
類的大小:
類的大小只與成員變量(非static數據成員變量)和虛函數指針有關,還要考慮到對齊。
對齊規則理解1:
1.數據成員對齊規則:struct, union的數據成員,第一個數據成員放在offset為0的地方,之后的數據成員的存儲起始位置都是放在該數據成員大小的整數倍位置。如在32bit的機器上,int的大小為4,因此int存儲的位置都是4的整數倍的位置開始存儲。
2.結構體作為數據成員的對齊規則:在一個struct中包含另一個struct,內部struct應該以它的最大數據成員大小的整數倍開始存儲。如 struct A 中包含 struct B, struct B 中包含數據成員 char, int, double,則 struct B 應該以sizeof(double)=8的整數倍為起始地址。
3.收尾工作的對齊規則:整個struct的大小,應該為最大數據成員大小的整數倍。
假設在64位機器下
class test1 {int a; //內存位置:[0]..[3]char b; //內存位置:[4]int* c; //內存位置:[8]..[15] } sizeof(test1) = 16class test2 {short x; //內存位置:[0]..[1]double y; //內存位置:[8]..[15]test1 t; //內存為止:[16]..[32]char z; //內存為止:[17] } sizeof(test2) = 2 + (6) + 8 + 16 + 1 + (7) = 40對齊規則理解2:
輸出:12
class test2 { private:int i;//4bytechar c = '1';//1byte short s = 2;//2byte };int main(){cout << sizeof(test2) << endl;return 0; }?輸出:8
我們可以看到。類test和test2的成員變量完全一樣,只是定義順序不一樣,卻造成了2個類占用內存大小不一樣。而這就是編譯器內存對齊的緣故。
(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。
c語言中變量存儲為什么要內存對齊?
為了有助于加快計算機的取數速度,編譯器默認會對結構體進行處理(實際上其它地方的數據變量也是如此),讓寬度為2的基本數據類型(short等)都位于能被2整除的地址上,讓寬度為4的基數據類型(int等)都位于能被4整除的地址上,以此類推。這樣,兩個數中間就可能需要加入填充字節,所以整個結構體的sizeof值就增長了。
字節對齊的細節和編譯器實現相關,但一般而言,滿足三個準則: 1) 結構體變量的首地址能夠被其最寬基本類型成員的大小所整除; 2) 結構體每個成員相對于結構體首地址的偏移量(offset)都是成員大小的整數倍,如有需要編譯器會在成員之間加上填充字節(internal adding); 3) 結構體的總大小為結構體最寬基本類型成員大小的整數倍,如有需要編譯器會在最末一個成員之后加上填充字節(trailing padding)。
總結
以上是生活随笔為你收集整理的C++笔记——有关内存对齐的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 华为Mate50“捅破天”的背后:研发团
- 下一篇: s3c2440移植MQTT