面試 結構體大小的計算

2021-10-01 05:41:23 字數 2354 閱讀 9063

1.  什麼是記憶體對齊

舉例:

typedef struct a;
sizeof(a) = 24

typedef struct b;
sizeof(b) = 16

分別對他們求大小,sizeof(a),sizeof(b)我們所得到的結果是不同的,sizeof(a)=24而sizeof(b)=16為什麼會產生不一樣的結果呢? 

這是非常簡單的乙個例子,體現了結構體的記憶體對齊規則。 在結構體中,從結構體的首位址開始,假設位址從0開始。 

對結構體a來說,a佔4個位元組,佔從0~3的位元組,b是double型別佔8個位元組,佔從8~15的位元組,c佔兩個位元組,從16~17的位元組。 

對結構體b來說,a佔4個位元組,從0~3,b佔兩個位元組從4~6;c佔8個位元組從8~15。 

對齊規則:

1、按照成員的宣告順序,依次安排記憶體,

2、其偏移量為成員大小的整數倍,0看做任何成員的整數倍,

3、最後結構體的大小為最大成員的整數倍(所以這裡的a的大小是24,而不是18)。

2.  c語言和c++中空類和空結構體的大小 :

在c++中規定了空結構體和空類的記憶體所佔大小為1位元組,因為c++中規定,任何不同的物件不能擁有相同的記憶體位址。 

而在c語言中,空的結構體在記憶體中所佔大小為0。(gcc中測試為0,其他編譯器不一定)

3.  為什麼要記憶體對齊?

1.平台原因(移植原因):不是所有的硬體平台都能訪問任意位址上的任意資料的;某些硬體平台只能在某些位址處取某些特定型別的資料,否則丟擲硬體異常。 

2.效能原因:資料結構(尤其是棧)應該盡可能地在自然邊界上對齊。原因在於,為了訪問未對齊的記憶體,處理器需要作兩次記憶體訪問;而對齊的記憶體訪問僅需要一次訪問。

參考部落格:

解釋一:

每個特定平台上的編譯器都有自己的預設「對齊係數」(也叫對齊模數)。程式設計師可以通過預編譯命令#pragma pack(n),n=1,2,4,8,16來改變這一係數,其中的n就是你要指定的「對齊係數」。

規則:

1.  資料成員對齊規則:結構(struct)(或聯合(union))的資料成員,第乙個資料成員放在offset為0的地方,以後每個資料成員的對齊按照#pragma pack指定的數值和這個資料成員自身長度中,比較小的那個進行。

2.  結構(或聯合)的整體對齊規則:在資料成員完成各自對齊之後,結構(或聯合)本身也要進行對齊,對齊將按照#pragma pack指定的數值和結構(或聯合)最大資料成員長度中,比較小的那個進行。

解釋二:

n 位元組的對齊方式 vc 對結構的儲存的特殊處理確實提高 cpu 儲存變數的速度,但是有時候也帶來 了一些麻煩,我們也遮蔽掉變數預設的對齊方式,自己可以設定變數的對齊方式。 vc 中提供了#pragma pack(n)來設定變數以 n 位元組對齊方式。n 位元組對齊就是說 變數存放的起始位址的偏移量有兩種情況:

第一、如果 n 大於等於該變數所占用的字 節數,那麼偏移量必須滿足預設的對齊方式。

第二、如果 n 小於該變數的型別所占用 的位元組數,那麼偏移量為 n 的倍數,不用滿足預設的對齊方式。結構的總大小也有個 約束條件,分下面兩種情況:如果 n 大於所有成員變數型別所占用的位元組數,那麼結 構的總大小必須為占用空間最大的變數占用的空間數的倍數; 否則必須為 n 的倍數。

下面舉例說明其用法。 #pragma pack(push) //儲存對齊狀態

#pragma pack(4)//設定為 4 位元組對齊

struct test ; #pragma pack(pop)//恢復對齊狀態 以上結構體的大小為 16:

下面分析其儲存情況,首先為 m1 分配空間,其偏移量 為 0,滿足我們自己設定的對齊方式(4 位元組對齊),m1 大小為 1 個位元組。接著開始 為 m4 分配空間,這時其偏移量為 1,需要補足 3 個位元組,這樣使偏移量滿足為 n=4 的倍數(因為 sizeof(double)大於 4),m4 占用 8 個位元組。接著為 m3 分配空間,這時 其偏移量為 12,滿足為 4 的倍數,m3 占用 4 個位元組。這時已經為所有成員變數分配 了空間,共分配了 16 個位元組,滿足為 n 的倍數。如果把上面的#pragma pack(4)改為 #pragma pack(8),那麼我們可以得到結構的大小為 24。

參考部落格:

參考部落格:

計算結構體大小

運算子sizeof可以計算出給定型別的大小,對於32位系統來說,sizeof char 1 sizeof int 4。基本資料型別的大小很好計算,我們來看一下如何計算構造資料型別的大小。c語言中的構造資料型別有三種 陣列 結構體和共用體。陣列是相同型別的元素的集合,只要會計算單個元素的大小,整個陣列...

計算結構體大小

include include include define uint32 unsigned int define uint16 unsigned short define uint8 unsigned char define bool unsigned char 位元組型別列舉 enum type...

結構體大小的計算

位元組對齊原則 結構體預設的位元組對齊一般滿足三個準則 1 結構體變數的首位址能夠被其最寬基本型別成員的大小所整除 2 結構體每個成員相對於結構體首位址的偏移量 offset 都是成員大小的整數倍,如有需要編譯器會在成員之間加上填充位元組 internal adding 3 結構體的總大小為結構體最...