C中位元組對齊問題

2021-06-23 05:25:15 字數 1599 閱讀 5671

好多筆試中,會考結構體的sizeof是多少,這就涉及到了位元組對齊問題。(vc或gcc編譯器,預設按4位元組對齊)

什麼叫位元組對齊?

就是資料在記憶體中存放的方式,它存放的位址需要是它長度的整數倍。比如單位元組放在什麼位址都可以,雙位元組資料只能存放在偶位址上,4位元組數只能存放在是4的倍數的位址上。

注意:它與cpu訪問的方式無關,32位機器就是按照4位元組來訪問的,因為它的資料匯流排是32位,不會以資料在記憶體中的對齊方式而變化。

一、對於標準資料型別,它的位址是他長度的整數倍就行了。

char:1位元組對齊(有符號無符號一樣)

short:2

int:4

long:4

float:4

double:8

二、對於非標準型別,對齊方式如下:

1、陣列:按照基本資料型別對齊,只要第乙個資料對齊了,後面的自然就對齊了。

2、聯合體:按照元素中最大的長度對齊。

3、結構體:結構中每個資料都要對齊。

其中,因為結構體對齊最複雜,所以也最常見。

下面舉幾個結構體例子:

1、struct st1 ;

它佔幾個位元組呢?正確答案是:20

分析如下:char本來佔1個位元組,因為4位元組對齊,所以需要在x1後空出3個位元組,接下來才是x2.x3本來佔10個位元組,但由於最後兩個位元組後面也需要空出2個位元組,所以x3佔12個位元組。這樣4+4+12=20個位元組。

2、如下兩個類似的結構體,成員相同,只是順序不同,則所佔位元組不同。

struct a ;

struct b ;

正確答案:a佔12個位元組,b佔8個位元組。

分析:a:a(1個位元組)之後是b(4個位元組),需要在a之後空著3個位元組。4+4+4=12.

b:b先佔4個位元組,緊接著a佔1個位元組,然後c佔2個位元組,那麼只需要在a之後空1個位元組就可以存放c。所以4+2+2=8.

當然,可以不採取預設的對齊方式,可以手工修改任意位元組對齊,這個只是修改編譯器的對齊方式,只是改變了編譯出來的資料的排列方式而已,cpu依舊是按照4位元組訪問的。

人工修改位元組對齊方式有2種方式:

1、#pragma pack(n)與#pragma pack() n位元組對齊如:

#pragma pack (2) /*指定按2位元組對齊*/

struct c

;#pragma pack () /*取消指定對齊,恢復預設對齊*/

sizeof(struct c)值就變為8。

2、__attribute((aligned (n)))與__attribute__((packed))    

使用如下:

struct a

__attrubute__ ((aligned(1)));

1位元組對齊,則sizeof(a)=15。

struct a

__attrubute__ ((packed));

取消結構在編譯過程中的優化對齊,按照實際占用位元組數進行對齊,是gcc特有的語法。

問:什麼時候需要手動設定對齊方式呢?

答:實際工程中,當在不同cpu下,設計通訊協議時,或編寫硬體驅動程式時(需要用結構體來描述暫存器結構),需要手動設定。即使看起來就自然對齊的也要手動對齊,以免不同的編譯器生成的**不一樣。

C 位元組對齊問題

關於c 位元組對齊問題 關於c c 的位元組對齊 這兩天寫解析swf檔案的程式,在結構體指標和從檔案中讀出來的進行轉換的時候遇到一些問題,就是有乙個struct a,例如 struct a char flag int length int id 然後乙個飄逸的 struct a a struct a...

C 位元組對齊問題

關於c 位元組對齊問題 關於c c 的位元組對齊 這兩天寫解析swf檔案的程式,在結構體指標和從檔案裡讀出來的進行轉換的時候遇到一些問題,就是有乙個struct a,比如 struct a char flag int length int id 然後乙個飄逸的 struct a a struct a...

c 記憶體中位元組對齊問題詳解

c 記憶體中位元組對齊問題詳解 一 什麼是位元組對齊,為什麼要對齊?現代計算機中記憶體空間都是按照byte劃分的,從理論上講似乎對任何型別的變數的訪問可以從任何位址開始,但實際情況是在訪問特定型別變數的時候經常在特 定的記憶體位址訪問,這就需要各種型別資料按照一定的規則在空間上排列,而不是順序的乙個...