c 基礎知識 六 結構體位元組對齊

2021-10-13 06:05:06 字數 891 閱讀 5564

我們在使用結構體的時候,有沒有發現這樣的情況,用sizeof(結構體)算出來的記憶體位元組數與結構體裡面的資料所佔記憶體位元組數總和不匹配。

比如以下:

struct a

;本來總共應該是7個位元組

但是用sizeof(結構體)算出來卻是12個位元組

今天我們來看看到底是怎麼回事呢?原來啊,是編譯器幫我們做了位元組對齊。做位元組對齊的目的是提高記憶體的訪問效率。

比如32位cpu,每個匯流排週期都是偶數的位址開始訪問讀取32位的資料,但是如果資料不是按從偶數開始放置的,則讀取則需要兩個匯流排週期才能讀到想要的資料。因此需要在記憶體存放資料時做記憶體對齊。

記憶體對齊需要遵守兩個基本原則:

1、對於結構體的成員,第乙個資料偏移位址為0,後面的資料的偏移量需要是其所佔記憶體大小的整數倍。否則的話就需要進行填充位元組數。

舉栗子:

比如結構體a,很明顯第乙個成員為a,所以它的偏移位址為0,按照該原則,b占用是4個位元組,所以b相對於a的偏移位址必須是4個整數倍,則最小為4,因為a占用1個位元組,所以需要在a,b之間填充3個位元組來進行位元組記憶體對齊。同理,b的便宜位址變為了4,b本身佔4個位元組。b的位址為4----8,c的偏移位址就為8,本身佔2個位元組,偏移量是所佔大小的4倍,不需要填充。

2、結構體所有資料記憶體對齊後,但是結構體也需要記憶體對齊,其整個結構體記憶體大小必須是結構體內中資料所佔記憶體最大的整數倍。

同樣看結構體a,從1中我們知道a,b之間填充了3個位元組,bc沒有填充,總共佔據了1+3+4+2=10個位元組。根據原則2,結構體大小必須為4(因為該結構體資料中最大佔4個位元組)倍數,所以末尾再填充兩個位元組,總共是12個位元組。

3、如果程式中有#pragma pack(n) 預編譯指令,則所有成員對齊以n位元組為準(即偏移量為n的整數倍),不在考慮當前型別以及最大結構體型別。

結構體位元組對齊

include pragma pack 2 struct t.pragma pack int main int argc,char argv 最後輸出的結果為 8。這個表示是按照2位元組來對齊資料,首先分配2位元組給成員變數i,分配完成後,還剩一位元組,zj add補0 沒法容納成員變數d,此時會再...

結構體位元組對齊

include pragma pack 2 struct t.pragma pack int main int argc,char argv 最後輸出的結果為 8。這個表示是按照2位元組來對齊資料,首先分配2位元組給成員變數i,分配完成後,還剩一位元組,zj add補0 沒法容納成員變數d,此時會再...

結構體位元組對齊

在用sizeof運算子求算某結構體所佔空間時,並不是簡單地將結構體中所有元素各自佔的空間相加,這裡涉及到記憶體位元組對齊的問題。從理論上講,對於任何 變數的訪問都可以從任何位址開始訪問,但是事實上不是如此,實際上訪問特定型別的變數只能在特定的位址訪問,這就需要各個變數在空間上按一定的規則排列,而不是...