C語言的位元組對齊及 pragma pack的使用

2021-06-01 09:36:21 字數 3276 閱讀 3125

posted on 2010-04-15 11:14

delcpp 閱讀(623)

編輯收藏

c編譯器的預設位元組對齊方式(自然對界)

在預設情況下,c編譯器為每乙個變數或是資料單元按其自然對界條件分配空間。

在結構中,編譯器為結構的每個成員按其自然對界(alignment)條件分配空間。各個成員按照它們被宣告的順序在記憶體中順序儲存(成員之間可能有插入的空位元組),第乙個成員的位址和整個結構的位址相同。

c編譯器預設的結構成員自然對界條件為「n位元組對齊」,n即該成員資料型別的長度。如int型成員的自然對界條件為4位元組對齊,而double型別的結構成員的自然對界條件為8位元組對齊。若該成員的起始偏移不位於該成員的「預設自然對界條件」上,則在前乙個節面後面新增適當個數的空位元組。

c編譯器預設的結構整體的自然對界條件為:該結構所有成員中要求的最大自然對界條件。若結構體各成員長度之和不為「結構整體自然對界條件的整數倍,則在最後乙個成員後填充空位元組。

例子1(分析結構各成員的預設位元組對界條界條件和結構整體的預設位元組對界條件):

struct

test

;

因為test結構體中,最大的成員為flaot x3,因些此結構體的自然對界條件為4位元組對齊。則結構體長度就為12位元組,記憶體布局為1100 1111 1000。

例子2:

#include 

<

stdio.h

>

//#pragma pack(2)

typedef

struct

testlength1;

intlength1

=sizeof

(testlength1);

//4個位元組對齊,占用位元組1111 1011 1000,length = 12

typedef

struct

testlength2;

intlength2

=sizeof

(testlength2);

//4個位元組對齊,占用位元組1011 1111 1000,length = 12

typedef

struct

testlength3;

intlength3

=sizeof

(testlength3);

//4個位元組對齊,占用位元組1100 1111 1100,length = 12

typedef

struct

testlength4;

intlength4

=sizeof

(testlength4);

//4個位元組對齊,占用位元組1111 1111,length = 8

intmain(

void

)

改變預設的對界條件(指定對界)

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

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

這時,對齊規則為:

1、資料成員對齊規則:結構(struct)(或聯合(union))的資料成員,第乙個資料成員放在offset為0的地方,以後每個資料成員的對齊按照#pragma pack指定的數值和這個資料成員自身長度中,比較小的那個進行。

2、結構(或聯合)的整體對齊規則:在資料成員完成各自對齊之後,結構(或聯合)本身也要進行對齊,對齊將按照#pragma pack指定的數值和結構(或聯合)最大資料成員長度中,比較小的那個進行。

結合1、2推斷:當#pragma pack的n值等於或超過所有資料成員長度的時候,這個n值的大小將不產生任何效果。

因此,當使用偽指令#pragma pack (2)時,test結構體的大小為8,記憶體布局為11 11 11 10。

需要注意一點,當結構體中包含乙個子結構體時,子結構中的成員按照#pragma pack指定的數值和子結構最大資料成員長度中,比較小的那個進行進行對齊。例子如下:

#pragma pack(8)

struct s1;

struct s2;

#pragma pack()

sizeof(s2)的結果為24。s1的記憶體布局為1100 1111,s2的記憶體布局為1000 1100 1111 0000 1111 1111。

例子:

#include 

<

stdio.h

>

#pragma

pack(2)

typedef

struct

testlength1;

intlength1

=sizeof

(testlength1);

//2個位元組對齊,占用位元組11 11 10 11 10,length = 10

typedef

struct

testlength2;

intlength2

=sizeof

(testlength2);

//2個位元組對齊,占用位元組10 11 11 11 10,length = 10

typedef

struct

testlength3;

intlength3

=sizeof

(testlength3);

//2個位元組對齊,占用位元組11 11 11 11,length = 8

typedef

struct

testlength4;

intlength4

=sizeof

(testlength4);

//2個位元組對齊,占用位元組11 11 11 11,length = 8

intmain(

void

)

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

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

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

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

C語言的位元組對齊及 pragma pack的使用

c編譯器的預設位元組對齊方式 自然對界 在預設情況下,c編譯器為每乙個變數或是資料單元按其自然對界條件分配空間。在結構中,編譯器為結構的每個成員按其自然對界 alignment 條件分配空間。各個成員按照它們被宣告的順序在記憶體中順序儲存 成員之間可能有插入的空位元組 第乙個成員的位址和整個結構的位...

c語言位元組對齊

現代計算機中記憶體空間都是按照byte劃分的,從理論上講似乎對任何型別的變數的訪問可以從任何位址開始,但實際情況是在訪問特定型別變數的時候經常在特 定的記憶體位址訪問,這就需要各種型別資料按照一定的規則在空間上排列,而不是順序的乙個接乙個的排放,這就是對齊。基本資料型別自身對齊,也叫自然對齊。就是說...

C語言位元組對齊

一 概念 對齊跟資料在記憶體中的位置有關。如果乙個變數的記憶體位址正好位於它長度的整數倍,他就被稱做自然對齊。比如在32位cpu下,假設乙個整型變數的位址為0x00000004,那它就是自然對齊的。二 為什麼要位元組對齊 需要位元組對齊的根本原因在於cpu訪問資料的效率問題。假設上面整型變數的位址不...