C語言結構體之記憶體對齊

2022-05-26 05:48:08 字數 1755 閱讀 4835

首先看乙個例子,下面有乙個結構體:

struct

structtest1

;

假設這個結構體成員在記憶體中是緊湊排列的,那麼c1的儲存位址就是0,s的儲存位址是1-2,c2的儲存位址是3,i的儲存位址是4-7,c1的位址是0000000000000000,s的位址是0000000000000001,c2的位址是0000000000000003,i的位址是0000000000000004,整個結構體所佔記憶體是8。但是寫乙個程式輸出一下,則會得到不同的結果。

#include struct

structtest1

;int

main()

程式的輸出結果與我們**的結果不一致,這就是因為記憶體對齊導致的。

記憶體對齊就是,按照成員的宣告順序,依次安排記憶體,其偏移量為最大成員大小的整數倍,最後結構體的大小為最大成員的整數倍。

因為訪問未對齊的記憶體,處理器需要做兩次記憶體訪問,然而對齊的記憶體訪問僅需要一次訪問。預設情況下,編譯器預設將結構、棧中的成員資料進行記憶體對齊。編譯器將未對齊的成員往後移,將每乙個成員都對齊到自然邊界上,從而也導致了整個結構體的尺寸變大。儘管會犧牲一點空間(成員間有部分記憶體空閒),但提高了效能。

乙個小技巧就是將上面的結構體寫成下面的形式:

struct

structtest1

;

這樣一來,每個成員都對齊在其自然邊界上,從而避免了編譯器自動對齊。

除此之外我們還可以利用#pragma pack()來改變編譯器的預設對齊方式

使用指令#pragma pack (n),編譯器將按照 n 個位元組對齊。

使用指令#pragma pack (),編譯器將取消自定義位元組對齊方式。

在#pragma pack (n)和#pragma pack ()之間的**按 n 個位元組對齊。

當n=1時:

#include #pragma pack(1)

struct

teststruct1

;struct

teststruct2

;#pragma pack()

intmain()

當n=2時

#include #pragma pack(2)

struct

teststruct1

;struct

teststruct2

;#pragma pack()

intmain()

當n=4時

#include #pragma pack(4)

struct

teststruct1

;struct

teststruct2

;#pragma pack()

intmain()

當n=8時

#include #pragma pack(8)

struct

teststruct1

;struct

teststruct2

;#pragma pack()

intmain()

C語言結構體對齊 記憶體對齊問題

c語言結構體對齊也是老生常談的話題了。基本上是面試題的必考題。內容雖然很基礎,但一不小心就會弄錯。寫出乙個struct,然後sizeof,你會不會經常對結果感到奇怪?sizeof的結果往往都比你宣告的變數總長度要大,這是怎麼回事呢?有人給對齊原則做過總結,具體在 看到現在已記不起來,這裡引用一下前人...

C語言結構體的記憶體對齊

學過c語言的大家應該都學到過結構體,結構體是一種聚合資料型別,它可以把不同型別的資料儲存在一起,我們把結構體中儲存的資料叫做結構體成員。了解了結構體後,我們來談一談結構體在計算機系統中是如何儲存的,首先,我們來看看下面這段 struct a int main 這段 中我們分別定義了三個結構體成員,按...

解析C語言結構體對齊 記憶體對齊問題

c語言結構體對齊也是老生常談的話題了。基本上是面試題的必考題。內容雖然很基礎,但一不小心就會弄錯。寫出乙個struct,然後sizeof,你會不會經常對結果感到奇怪?sizeof的結果往往都比你宣告的變數總長度要大,這是怎麼回事呢?有人給對齊原則做過總結,具體在 看到現在已記不起來,這裡引用一下前人...