C C 結構體和類中的記憶體對齊

2021-07-05 08:38:42 字數 1835 閱讀 7875

在對結構體或者類進行 sizeof 的時候,其涉及到記憶體對齊的相關規則。了解記憶體對齊的規則,我們便可以通過指標去訪問類或結構體中的成員(對於我們理解結構體和類的記憶體布局以及指標的用法有極大好處)。

先來看乙個例子:

typedef struct s_a;

typedef struct s_b;
sizeof(s_a) = ?   sizeof(s_b) = ? 想一想這個問題?

答案是sizeof(s_a) = 24,   sizeof(s_b) = 16。這是非常簡單的乙個例子,體現了結構體的記憶體對齊規則。

在結構體中,從結構體的首位址開始,定義偏移量0。

對於結構體s_b,a的偏移量為0,佔4個位元組(0 - 3),b的偏移量為4,佔2個位元組(4 - 5),c的偏移量為8,佔8個位元組(8 - 15)。

對於結構體s_a,a的偏移量為0,佔4個位元組(0 - 3),c的偏移量為8,佔8個位元組(8 - 15),b的偏移量為16,佔2個位元組(16 - 17)。

這就是記憶體對齊,對齊規則是按照成員的宣告順序,依次安排記憶體,其偏移量為成員大小的整數倍,0看做任何成員的整數倍,最後結構體的大小為最大成員的整數倍(所以這裡的s_a的大小是24,而不是18)。

另外對於一些特殊的成員,比如結構體巢狀或者陣列,看下面例子。

#include #include #define objoff(obj,member) (((char*)&obj.member) - ((char*)&obj))

typedef struct s_a;

typedef struct

s_b;

int main(void)

輸出sizeof(s_b) = 20。 對於結構體中巢狀了其他結構體時在進行記憶體對齊的時候,巢狀結構體的對齊值為巢狀結構體中最大成員(這裡的int c)的整數倍,意思是成員結構體的開始(這裡的char d)偏移量是巢狀結構體最大成員(這裡的int c)大小的整數倍。

這裡有個對齊值的概念,一般都有乙個預設的對齊值8,對齊值可以使用#pragram pack (x)   將對齊值修改為x,一般進行對齊的時候會使用min(資料成員大小,預設對齊值)進行對齊。對於巢狀結構體,巢狀結構體進行對齊的時候,首個巢狀結構體的成員將按照巢狀結構體的對齊值(min(資料成員大小,預設對齊值))進行對齊。

s_b的記憶體布局如下:

對於包含陣列的情況,如果是基本資料型別的話,就相當於宣告了多個連續的相同型別的成員,如果是結構體陣列的話,也可以看做連續宣告的成員,不同的是結構體成員與其他成員是隔離開來的(見上一段文字)。例子如下:

typedef struct s_a;

typedef struct

s_b;

其中s_b的記憶體布局應該是這樣的:

接下來再來說說類中的記憶體對齊。

類的記憶體對齊和結構體的記憶體對齊類似,不過需要注意的是,類中如果出現靜態成員變數,靜態成員變數的大小是不會計入到類的大小中的,普通函式也不會對類大小有影響。如果是虛函式的話,在類的記憶體中首先會存虛函式表的指標,這些知識可以去找找其他資料,推薦去看看陳皓的c++ 虛函式表解析,寫得非常詳細。

我是一名剛進入大三的學生,文筆也不太行。寫的不太清楚的地方請見諒,如有錯誤,歡迎指正。

C C 記憶體對齊(一) 結構體

記憶體管理是c c 程式設計非常重要的一部分內容,熟悉c c 中一些常見資料結構和資料型別的記憶體分布情況,可以很大程度上降低了coding過程中記憶體洩漏和越界等比較嚴重的記憶體問題,下面主要討論一下結構體 類中同樣存在記憶體對齊,記憶體對齊會複雜一些,涉及到虛表等問題,後面介紹類的時候會提到 中...

結構體對齊(記憶體對齊

有的時候,在腦海中停頓了很久的 顯而易見 的東西,其實根本上就是錯誤的。就拿下面的問題來看 structt 使用sizeof t 將得到什麼樣的答案呢?要是以前,想都不用想,在32位機中,int是4個位元組,char是1個位元組,所以t一共是5個位元組。實踐出真知,在vc6中測試了下,答案確實8個位...

記憶體對齊 結構體對齊

現在已知32位機器上各種資料型別的長度如下 char 1 有符號無符號同 short 2 有符號無符號同 int 4 有符號無符號同 long 4 有符號無符號同 float 4 double 8 重要規則 1,複雜型別中各個成員按照它們被宣告的順序在記憶體中順序儲存,第乙個成員的位址和整個型別的位...