C++笔记——有关内存对齐
類的大小:
類的大小只與成員變量(非static數(shù)據(jù)成員變量)和虛函數(shù)指針有關(guān),還要考慮到對(duì)齊。
對(duì)齊規(guī)則理解1:
1.數(shù)據(jù)成員對(duì)齊規(guī)則:struct, union的數(shù)據(jù)成員,第一個(gè)數(shù)據(jù)成員放在offset為0的地方,之后的數(shù)據(jù)成員的存儲(chǔ)起始位置都是放在該數(shù)據(jù)成員大小的整數(shù)倍位置。如在32bit的機(jī)器上,int的大小為4,因此int存儲(chǔ)的位置都是4的整數(shù)倍的位置開始存儲(chǔ)。
2.結(jié)構(gòu)體作為數(shù)據(jù)成員的對(duì)齊規(guī)則:在一個(gè)struct中包含另一個(gè)struct,內(nèi)部struct應(yīng)該以它的最大數(shù)據(jù)成員大小的整數(shù)倍開始存儲(chǔ)。如 struct A 中包含 struct B, struct B 中包含數(shù)據(jù)成員 char, int, double,則 struct B 應(yīng)該以sizeof(double)=8的整數(shù)倍為起始地址。
3.收尾工作的對(duì)齊規(guī)則:整個(gè)struct的大小,應(yīng)該為最大數(shù)據(jù)成員大小的整數(shù)倍。
假設(shè)在64位機(jī)器下
class test1 {int a; //內(nèi)存位置:[0]..[3]char b; //內(nèi)存位置:[4]int* c; //內(nèi)存位置:[8]..[15] } sizeof(test1) = 16class test2 {short x; //內(nèi)存位置:[0]..[1]double y; //內(nèi)存位置:[8]..[15]test1 t; //內(nèi)存為止:[16]..[32]char z; //內(nèi)存為止:[17] } sizeof(test2) = 2 + (6) + 8 + 16 + 1 + (7) = 40對(duì)齊規(guī)則理解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個(gè)類占用內(nèi)存大小不一樣。而這就是編譯器內(nèi)存對(duì)齊的緣故。
(1)對(duì)于類test的內(nèi)存空間是這樣的:
內(nèi)存分配過(guò)程:
1、char和編譯器默認(rèn)的內(nèi)存缺省分割大小比較,char比較小,分配一個(gè)字節(jié)給它。
2、int和編譯器默認(rèn)的內(nèi)存缺省分割大小比較,int比較小,占4字節(jié)。只能空3個(gè)字節(jié),重新分配4個(gè)字節(jié)。
3、short和編譯器默認(rèn)的內(nèi)存缺省分割大小比較,short比較小,占2個(gè)字節(jié),分配2個(gè)字節(jié)給它。
4、對(duì)齊結(jié)束類本身也要對(duì)齊,所以最后空余的2個(gè)字節(jié)也被test占用。
(2)對(duì)于類test2的內(nèi)存空間是這樣的:
1、int和編譯器默認(rèn)的內(nèi)存缺省分割大小比較,int比較小,占4字節(jié)。分配4個(gè)字節(jié)給int。
2、char和編譯器默認(rèn)的內(nèi)存缺省分割大小比較,char比較小,分配一個(gè)字節(jié)給它。
3、short和編譯器默認(rèn)的內(nèi)存缺省分割大小比較,short比較小,此時(shí)前面的char分配完畢還余下3個(gè)字節(jié),足夠short的2個(gè)字節(jié)存儲(chǔ),所以short緊挨著。分配2個(gè)字節(jié)給short。
c語(yǔ)言中變量存儲(chǔ)為什么要內(nèi)存對(duì)齊?
為了有助于加快計(jì)算機(jī)的取數(shù)速度,編譯器默認(rèn)會(huì)對(duì)結(jié)構(gòu)體進(jìn)行處理(實(shí)際上其它地方的數(shù)據(jù)變量也是如此),讓寬度為2的基本數(shù)據(jù)類型(short等)都位于能被2整除的地址上,讓寬度為4的基數(shù)據(jù)類型(int等)都位于能被4整除的地址上,以此類推。這樣,兩個(gè)數(shù)中間就可能需要加入填充字節(jié),所以整個(gè)結(jié)構(gòu)體的sizeof值就增長(zhǎng)了。
字節(jié)對(duì)齊的細(xì)節(jié)和編譯器實(shí)現(xiàn)相關(guān),但一般而言,滿足三個(gè)準(zhǔn)則: 1) 結(jié)構(gòu)體變量的首地址能夠被其最寬基本類型成員的大小所整除; 2) 結(jié)構(gòu)體每個(gè)成員相對(duì)于結(jié)構(gòu)體首地址的偏移量(offset)都是成員大小的整數(shù)倍,如有需要編譯器會(huì)在成員之間加上填充字節(jié)(internal adding); 3) 結(jié)構(gòu)體的總大小為結(jié)構(gòu)體最寬基本類型成員大小的整數(shù)倍,如有需要編譯器會(huì)在最末一個(gè)成員之后加上填充字節(jié)(trailing padding)。
總結(jié)
以上是生活随笔為你收集整理的C++笔记——有关内存对齐的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 华为Mate50“捅破天”的背后:研发团
- 下一篇: “国民神车”也沦陷了?车主购车三年后不付