C語言結構體的位元組對齊

2021-06-06 23:54:11 字數 2266 閱讀 5977

在c語言中,結構是一種復合資料型別,其構成元素既可以是基本資料型別(如int、long、float等)的變數,也可以是一些復合資料型別(如陣列、結構、聯合等)的資料單元。在結構中,編譯器為結構的每個成員按其自然對界(alignment)條件分配空間。各個成員按照它們被宣告的順序在記憶體中順序儲存,第乙個成員的位址和整個結構的位址相同。

例如,下面的結構各成員空間分配情況:

struct test

; 結構的第乙個成員x1,其偏移位址為0,佔據了第1個位元組。第二個成員x2為short型別,其起始位址必須2位元組對界,因此,編譯器在x2和x1之間填充了乙個空位元組。結構的第三個成員x3和第四個成員x4恰好落在其自然對界位址上,在它們前面不需要額外的填充位元組。在test結構中,成員x3要求4位元組對界,是該結構所有成員中要求的最大對界單元,因而test結構的自然對界條件為4位元組,編譯器在成員x4後面填充了3個空位元組。整個結構所佔據空間為12位元組。

更改c編譯器的預設位元組對齊方式

在預設情況下,c編譯器為每乙個變數或是資料單元按其自然對界條件分配空間。一般地,可以通過下面的方法來改變預設的對界條件:

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

· 使用偽指令#pragma pack (),取消自定義位元組對齊方式。

另外,還有如下的一種方式,一般在arm編譯器中使用:

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

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

以上的n = 1, 2, 4, 8, 16... 第一種方式較為常見。

#pragma pack(8)

struct s1;

struct s2;

#pragma pack()

問 1.sizeof(s2) = ?

2.s2的c後面空了幾個位元組接著是d?

sizeof(s2)結果為24.

成員對齊有乙個重要的條件,即每個成員分別對齊.即每個成員按自己的方式對齊.

也就是說上面雖然指定了按8位元組對齊,但並不是所有的成員都是以8位元組對齊.其對齊的規則是,每個成員按其型別的對齊引數(通常是這個型別的大小)和指定對齊引數(這裡是8位元組)中較小的乙個對齊.並且結構的長度必須為所用過的所有對齊引數的整數倍,不夠就補空位元組.

s1中,成員a是1位元組預設按1位元組對齊,指定對齊引數為8,這兩個值中取1,a按1位元組對齊;成員b是4個位元組,預設是按4位元組對齊,這時就按4位元組對齊,所以sizeof(s1)應該為8;

s2中,c和s1中的a一樣,按1位元組對齊,而d 是個結構,它是8個位元組,它按什麼對齊呢?對於結構來說,它的預設對齊方式就是它的所有成員使用的對齊引數中最大的乙個,s1的就是4.所以,成員d就是按4位元組對齊.成員e是8個位元組,它是預設按8位元組對齊,和指定的一樣,所以它對到8位元組的邊界上,這時,已經使用了12個位元組了,所以又新增了4個位元組的空,從第16個位元組開始放置成員e.這時,長度為24,已經可以被8(成員e按8位元組對齊)整除.這樣,一共使用了24個位元組.

a     b

s1的記憶體布局:11**,1111,

c    s1.a s1.b     d

s2的記憶體布局:1***,11**,1111,****11111111

這裡有三點很重要:

1.每個成員分別按自己的方式對齊,並能最小化長度

2.複雜型別(如結構)的預設對齊方式是它最長的成員的對齊方式,這樣在成員是複雜型別時,可以最小化長度

3.對齊後的長度必須是成員中最大的對齊引數的整數倍,這樣在處理陣列時可以保證每一項都邊界對齊

補充一下,對於陣列,比如:

char a[3];這種,它的對齊方式和分別寫3個char是一樣的.也就是說它還是按1個位元組對齊.

如果寫: typedef char array3[3];

array3這種型別的對齊方式還是按1個位元組對齊,而不是按它的長度.

不論型別是什麼,對齊的邊界一定是1,2,4,8,16,32,64....中的乙個.

測試的編譯器:

gcc 2.95 3.1 3.3 3.4 4.0

ms c/c++ 7.0 7.1 8.0 beta

borland c/c++ 5.6 6.0

intel c/c++ 7.0 8.0 8.1

digitalmars c/c++ 8.4

openwatcom 1.3

codeplay c/c++ 2.1.7

C語言結構體 位元組對齊

目的 犧牲一點空間,換時間的效率 cpu執行效率 最終結構體大小一定是4的倍數 32bit系統 結構體裡成員變數順序不一致,也會影響結構體的大小 資料型別 32位機大小 位元組 64位機大小 位元組 char11 short22 int4 4long48 指標型別48 double88 float4...

C語言結構體的位元組對齊

下面直接來看例子吧 測試環境為32位的系統 以下結構體分別佔多少位元組 struct a sizeof a 3 因為a b c按照1個位元組進行對齊 struct b sizeof b 8 按照4個位元組對齊 a佔4位元組 b佔乙個位元組 c佔2個位元組 有1個位元組剩餘 struct c size...

C語言結構體位元組對齊總結

首先說說為什麼要對齊。為了提高效率,計算機從記憶體中取資料是按照乙個固定長度的。以32位機為例,它每次取32個位,也就是4個位元組。位元組對齊有什麼好處?以int型資料為例,如果它在記憶體中存放的位置按4位元組對齊,也就是說1個int的資料全部落在計算機一次取數的區間內,那麼只需要取一次就可以了。如...