Linux下關於結構體對齊的總結

2021-06-23 08:39:05 字數 1261 閱讀 5095

許多實際的計算機系統對基本型別資料在記憶體中存放的位置有限制,它們會要求這些資料的首位址的值是某個數k(通常它為4或8)的倍數,這就是所謂的記憶體對齊,而這個k則被稱為該資料型別的對齊模數。當一種型別s的對齊模數與另一種型別t的對齊模數的比值是大於1的整數,我們就稱型別s的對齊要求比t強(嚴格),而稱t比s弱(寬鬆)。

對於基本資料型別(int char),他們占用的記憶體空間在乙個確定硬體系統下有個確定的值。而結構體成員記憶體分配情況卻有所不同。

就gun gcc編譯器而言,結構體的成員其對齊模數只能為1,2和4,或其整數倍,這一點和vs等編譯器不太相同。

1.        結構體變數的首位址能夠被其最寬基本型別成員的大小所整除;

備註:編譯器在給結構體開闢空間時,首先找到結構體中最寬的基本資料型別,然後尋找記憶體位址能被該基本資料型別所整除的位置,作為結構體的首位址。將這個最寬的基本資料型別的大小作為結構體的對齊模數。

2.         結構體每個成員相對於結構體首位址的偏移量(offset)都是成員大小的整數倍,如有需要編譯器會在成員之間加上填充位元組(internal adding);

備註:為結構體的乙個成員開闢空間之前,編譯器首先檢查預開闢空間的首位址相對於結構體首位址的偏移是否是本成員的整數倍,若是,則存放本成員,反之,則在本成員和上乙個成員之間填充一定的位元組,以達到整數倍的要求,也就是將預開闢空間的首位址後移幾個位元組。

3.         結構體的總大小為結構體最寬基本型別成員大小的整數倍,如有需要,編譯器會在最末乙個成員之後加上填充位元組。

備註:結構體總大小是包括填充位元組,最後乙個成員滿足上面兩條以外,還必須滿足第三條,否則就必須在最後填充幾個位元組以達到本條要求。

4.        對於結構體巢狀結構體,其對於仍按照基本資料型別拆分來分析。

此外,對於gun gcc而言,如果結構體沒有成員,也就是說定義如下結構體

struct test{} ,用sizeof求其長度,結果為0,但是在vs2008中,其長度為1。

雖然到現在也沒有看到gcc在linux系統下的使用 #pragma pack(n) 的記憶體對齊規則,但是從我測試的結果來看是這樣:預設的對齊是按照 int 型(4位元組)對齊,如果指定 #pragma pack(n) 中的 n 的話,n 不能大於預設對齊指定的長度,即如果預設對齊是 4 的話,n的取值可以是 1、2、4,超過 4 之後作為 4 處理。在 windows 等系統上似乎沒有這個限制。

Linux下關於結構體對齊的總結

許多實際的計算機系統對基本型別資料在記憶體中存放的位置有限制,它們會要求這些資料的首位址的值是某個數 k 通常它為4或 8 的倍數,這就是所謂的記憶體對齊,而這個 k則被稱為該資料型別的對齊模數。當一種型別 s的對齊模數與另一種型別 t的對齊模數的比值是大於 1的整數,我們就稱型別 s的對齊要求比t...

關於結構體的成員對齊與結構體整體對齊

大多數計算機體系結構中,對記憶體操作時按整字訪問才能達到最高效率,相當於是以空間換取時間,看似浪費了記憶體空間,但換來了訪問效率,先來說說三個概念 系統對齊值,自身對齊值,有效對齊值,三個概念的單位均為位元組,一開始概念不懂沒關係,可以對照後面的程式和記憶體分布圖來理解 1,系統對齊值 對於不同的作...

關於結構體位元組對齊

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