C語言 結構體內存對齊(計算結構體占用的位元組數)

2021-10-10 06:36:57 字數 2656 閱讀 2919

struct s

;

如果不考慮或者不存在記憶體對齊問題,這個結構體應該佔1+4+1 = 6個位元組,然而事實上它佔了12個位元組,???,這就涉及到記憶體對齊問題了。

結構體中的成員可以是不同的資料型別,成員按照定義時的順序依次儲存在連續的記憶體空間,和陣列不一樣的是,結構體的大小不是所有成員大小簡單的相加,需要考慮到系統在儲存結構體變數時的位址對齊問題

vs編譯器預設對齊(#pragma pack(n))的數值是8  linux下預設是4。

struct 是一種復合資料型別,其構成元素既可以是基本資料型別(如int、long、float 等)的變數,也可以是一些復合資料型別(如array、struct、union 等)的資料單元。對於結構體,編譯器會自動進行成員變數的對齊,以提高運算效率。預設情況下,編譯器為結構體的每個成員按其自然對界(natural alignment)條件分配空間。各個成員按照它們被宣告的順序在記憶體中順序儲存,第乙個成員的位址和整個結構的位址相同。

【注】自然對界(natural alignment)即預設對齊方式,是指按結構體的成員中size 最大的成員對齊。注:這裡的最大指整形資料,實型,結構體成員不在此例。見後面例項程式。

(1)結構體變數中成員的偏移量必須是成員大小的整數倍(0被認為是任何數的整數倍)(自然對界)、或者必須是指定對界的整數倍。

(2)結構體大小必須是所有成員大小的整數倍,也即所有成員大小的公倍數(自然對界)、或者指定對界的整數倍。

(2) 對於巢狀的結構體,需要將其展開。對結構體求sizeof時,上述兩種原則變為:

(1)展開後的結構體的第乙個成員的偏移量應當是被展開的結構體中最大的成員的整數倍。

(2)結構體大小必須是所有成員大小的整數倍,這裡所有成員計算的是展開後的成員,而不是將巢狀的結構體當做乙個整體。

一般地,可以通過下面的方法來改變預設的對界條件:

【注】如果#pragma pack (n)中指定的n 大於結構體中最大成員的size,則其不起作用,結構體仍然按照size 最大的成員進行對界。

另外,gcc還有如下的一種方式:

__attribute((aligned (n))),讓所作用的結構成員對齊在n位元組自然邊界上。如果結構中有成員的長度大於n,則按照最大成員的長度來對齊。

__attribute__ ((packed)),取消結構在編譯過程中的優化對齊,按照實際占用位元組數進行對齊。

(1)結構體變數中成員的偏移量必須是指定對界和成員大小相比較小的那個值的整數倍。

(2)結構體大小必須是指定對界和成員大小相比較小的那個值的整數倍。

(2) 對於巢狀的結構體,需要將其展開。對結構體求sizeof時,上述兩種原則變為:

(1)展開後的結構體的第乙個成員的偏移量應當是指定對界和成員大小相比較小的那個值的整數倍。

(2)結構體大小必須是指定對界和成員大小相比較小的那個值的整數倍。

struct s1

;printf("%d\n", sizeof(struct s1));

結果是8,我們來分析一下為什麼結果是 8??

我們來看一下記憶體分布圖:

結果是12,來看一下過程?

但是整個結構體為了整體對齊,得是4的整數倍,所以c2後面補三個位元組,那麼總大小就是12個位元組空間。所以輸出結果是12。

看一下記憶體分布圖:

結果是32,分析:

struct s3佔16個位元組。(8、1+3、4)

struct s4中有三個成員變數:

所以是32。

#pragma pack(2)

struct s1

;printf("%d\n", sizeof(struct s1));

指定為2位元組對齊,結構體大小為6位元組。

#pragma pack(2)

struct s2

;printf("%d\n", sizeof(struct s2));

指定為2位元組對齊,結構體大小為8位元組。

總共佔8位元組。

(2)效能原因:

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

缺點:無可厚非:這必然會存在效率問題,這是一種以空間換時間的做法,但這種做法是值得的

結構體內存對齊 計算結構體的大小

在求結構體的大小時,絕大部分情況下不會直接等於各個成員大小的總和,編譯器為了優化對結構體成員的訪問總會在結構體中插入一些空白位元組 記憶體對齊 例如 struct s1 printf d n sizeof s1 struct s3 printf d n sizeof s3 結構體s1和s3的大小並不...

結構體對齊 結構體內存布局

在c語言中,可以通過 pragma pack n 來指定結構體按n位元組對齊 這裡的n是2的較小整數次冪 如果程式設計者不指定對齊位元組數,那麼預設的會按照結構體中最長那一項對齊,如在64位作業系統中,當結構體中出現 void long 型別,則必然是按照8位元組對齊 當最大的是int,那麼就按照4...

C語言結構體內存對齊

1.效能原因 為了提高cup的效率訪問記憶體的速度,若是訪問未對齊的記憶體,處理器需要作兩次訪問 而訪問對齊的記憶體,則只需要一次訪問。2.編譯器相關 有的編譯器已經優化了記憶體對齊,所以記憶體對齊依賴於編譯器。參考 結構體對齊問題 說實話,規則看起來不太好理解,直接模仿下面步驟即可 以32位機器為...