<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
記憶體對齊的基本原則:
程式 1
class A{ }; int main() { cout << sizeof(A) << endl; // 1 }
對於一個什麼都沒有的空類,實際並不是空的,因為有預設的函數,具體可以參考 (待填入網址),大小是 1,這是因為需要有一個地址,C++ 不允許兩個不同的物件有相同的地址,所以 C++ 中空的類和結構體大小都是 1。
程式 2
class A{ A(){} ~A(){} void print() { printf("print()n"); } void foo() { printf("print()n"); } static void sprint() { printf("sprint()n"); } }; int main() { cout << sizeof(A) << endl; // 1 }
這個類的大小仍然是1,成員函數、靜態成員函數、靜態成員變數都是不佔用類的記憶體的,這是因為這些東西都是類的,而不是每個物件分別儲存。static變數就是儲存在全域性靜態區。
需要注意的是,子類繼承空類後,子類如果有自己的資料成員,而空基礎類別的1個位元組並不會加到子類中去。
程式 3
class Empty {}; struct D : public Empty { int a; };
sizeof(D)為4。
再來看另一種情況,一個類包含一個空類物件資料成員,則空類物件的大小仍為1。
程式 4
class Empty {}; class HaveAnInt { int x; Empty e; }
在大多數編譯器中,你會發現 sizeof(HaveAnInt) 輸出為8。這是由於,Empty類的大小雖然為1,然而為了記憶體對齊,編譯器會為HaveAnInt額外加上一些位元組,使得HaveAnInt被放大到足夠又可以存放一個int。
程式 1
class Data { char c; int a; }; cout << sizeof(Data) << endl;
程式 2
class Data { char c; double a; }; cout << sizeof(Data) << endl;
顯然程式 1 輸出的結果為 8,程式 2 輸出的結果為 16 .
程式 1 最大的資料成員是4bytes,1+4=5,補齊為4的倍數,也就是8。而程式 2 為8bytes,1+8=9,補齊為8的倍數,也就是16。
程式 3
class Data { char c; int a; char d; }; cout << sizeof(Data) << endl;
程式 4
class Data { char c; char d; int a; }; cout << sizeof(Data) << endl;
程式 3 執行結果為 12,程式 4 執行結果為 8
class中的資料成員放入記憶體的時候,記憶體拿出一個記憶體塊來,資料成員們排隊一個一個往裡放,遇到太大的成員時,不是將其劈成兩半能放多少就放多少,而是等下一個記憶體塊過來。這樣的話,就可以理解為什麼程式 3 和程式 4 兩段程式碼輸出結果不一樣了,因為程式 3 是
1 + (3) + 4 + 1 + (3) = 12,而程式 4 是1 + 1 + (2) + 4 = 8。括號中為補齊的bytes。
在預設條件下,記憶體對齊是以class中最大的那個基本型別為基準的,如果class中的資料成員包含其他class,則遞迴的取其中最大的基本型別來參與比較。
程式 1
class BigData { char array[33]; }; class Data { BigData bd; int integer; double d; }; cout << sizeof(BigData) << " " << sizeof(Data) << endl;
程式 2
class BigData { char array[33]; }; class Data { BigData bd; double d; }; cout << sizeof(BigData) << " " << sizeof(Data) << endl;
程式 1 和程式 2 執行結果均為:33 48
程式 1 和程式 2 中記憶體對其的基準均為8位元組,BigData的大小均為33。在程式 1 中,BigData接下來是個int(4bytes),能夠放下,這時候記憶體塊還剩3bytes,而接下來是個double(8bytes),放不下,所以要等下一個記憶體快到來。因此,程式 1 的Data的size = 33 + 4 + (3) + 8 = 48,同理程式 2 應該是
33 + (7) + 8 = 48。
程式 3
class A { public: double len; char str[33]; }; class B { public: A a; int b; }; cout << sizeof(A) << " " << sizeof(B) << endl;
以上程式碼輸出的結果為: 48 56
不同於程式 1 和程式 2 ,程式 3 中的class A實際會佔用41位元組,但會發生8位元組對齊,所以大小為48位元組。對於class B,成員b的起始位置已發生8位元組對齊,而class B整體還會發生8位元組對齊,所以最終大小為56。
C++ 的類中如果有虛擬函式,類內就會有一個虛擬函式表的指標 _vptr,指向自己的虛擬函式表,vptr 一般都是在類的最前邊(取決於編譯器的實現)。
class A { public: A(){} virtual ~A(){} virtual void foo(){} virtual void print() {} };
由於只是存一個指向虛擬函式表的指標,所以不管有多少個虛擬函式,都是 4 位元組大小(32位元下,任何指標大小都是 4,64位元下,任何指標大小都是 8),比如上面這個類 A,size 就是 4。
需要注意的是就是,對於沒有 override 的虛擬函式,基礎類別和子類中 _vptr 指向的虛擬函式表中,這個虛擬函式的地址是一樣的,也就是上邊的 foo() 函數,而對於重寫了的或者預設重寫的解構函式來說,_vptr 指向的虛擬函式表中,函數地址是不一樣的(當然兩個類的 _vptr 地址也是不一樣的,這是肯定的),這就能窺探到多型的實現了。
不同的編譯器對繼承後類的大小的計算方式不同,有的是先繼承後對齊,有的是先對齊後繼承。
class A { int i; char c1; } class B:public A { char c2; } class C:public B { char c3; }
sizeof(C)結果是多少呢,gcc和vs給出了不同的結果,分別是8、16。
記憶體對齊的意義
比較兩個結構體可以使用memcmp(void*, void*)嗎?
不可以,memcmp函數是逐個位元組進行比較的,而struct存在記憶體對齊,記憶體對齊時補的位元組內容是垃圾值,所以無法比較。
到此這篇關於C++記憶體對齊的實現的文章就介紹到這了,更多相關C++記憶體對齊內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45