記憶體對齊和cpu有關係,可以認為記憶體對齊的大小就是cpu一次讀取記憶體的大小,例如32cpu一次讀取4位元組,那麼記憶體的對齊方式就4位元組,64位就是8位元組。本質上是保證cpu使用盡量少的次數將某乙個變數取出來。關於結構體內存對齊的方式,只需要把握兩點即可:
上面說了,編譯預設對齊方式是4位元組(32位系統)或者8位元組(64)位系統,但是通過pragma pack可以自己定義記憶體的對齊方式。
#pragma pack(n)
// n = 1,2,4,8,16......
#include
//#pragma pack(2)
//#pragma pack(4)
struct node
;int
main
(void
)// 輸出:
當 #pragma pack(2
) 時, len =
10當 #pragma pack(4
) 時, len =
12當 #pragma pack(8
) 時, len =
12當 不使用#pragma pack
(n) 時, len =
12
對照上面的例項,下面講解具體原則。
對於結構體的各個成員,第乙個成員的偏移量是0,後面的成員其當前偏移量必須是當前成員型別大小的整數倍。
上面的案例中,在預設的對齊方式中,e的偏移量必須是4的倍數,因為e佔4個位元組,所以f要補齊3個位元組,使e偏移量為4。f偏移量為0,a的偏移量為2的倍數是8,d的偏移量為1的倍數,為11。
結構體內所有資料成員各自記憶體對齊後,結構體本身還要進行一次記憶體對齊,保證整個結構體占用記憶體大小是結構體內最大資料成員的最小整數倍。
上面可知,d的偏移量為11,其實11個位元組就可以存下,但是整體的大小必須是最大成員e的倍數,因此至少為12,d需要補齊乙個位元組。
即使用#pragma pack(n)預編譯指令。
如果程式中使用#pragma pack(n),則忽略上面的兩個原則。只需遵循以下面兩個新原則:
1、成員對齊
2、整體對齊
記憶體對齊及 pragma pack的使用
在預設情況下,c編譯器為每乙個變數或是資料單元按其自然對界條件分配空間。在結構中,編譯器為結構的每個成員按其自然對界 alignment 條件分配空間。各個成員按照它們被宣告的順序在記憶體中順序儲存 成員之間可能有插入的空位元組 第乙個成員的位址和整個結構的位址相同。c編譯器預設的結構成員自然對界條...
位元組對齊 pragma pack
這是給編譯器用的引數設定,有關結構體位元組對齊方式設定,pragma pack是指定資料在記憶體中的對齊方式。pragma pack n 作用 c編譯器將按照n個位元組對齊。pragma pack 作用 取消自定義位元組對齊方式。pragma pack push,1 作用 是指把原來對齊方式設定壓棧...
資料在記憶體中對齊方式 pragma pack
在程式中,有的時候我們定義結構體的時候,要用 pragma pack push,1 pragma pack pop 類似 將結構體包起來。一般形式如下 pragma pack push,1 struct a pragma pack pop 這麼做有什麼目的呢?注 下列內容來自網路。2 pragma ...