c語言記憶體對齊詳解

2021-08-14 17:46:01 字數 2286 閱讀 7607

一、什麼是位元組對齊,為什麼要對齊?

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

對齊的作用和原因:各個硬體平台對儲存空間的處理上有很大的不同。一些平台對某些特定型別的資料只能從某些特定位址開始訪問。比如有些架構的cpu在訪問乙個沒有進行對齊的變數的時候會發生錯誤,那麼在這種架構下程式設計必須保證位元組對齊.其他平台可能沒有這種情況,但是最常見的是如果不按照適合其平台要求對資料存放進行對齊,會在訪問效率上帶來損失。比如有些平台每次讀都是從偶位址開始,如果乙個int型(假設為32位系統)如果存放在偶位址開始的地方,那 麼乙個讀週期就可以讀出這32bit,而如果存放在奇位址開始的地方,就需要2個讀週期,並對兩次讀出的結果的高低位元組進行拼湊才能得到該32bit資料。顯然在讀取效率上下降很多。

二、請看下面的結構:

struct

struct1

;

sizeof(struct1) = ?

錯誤的求法:

sizeof(struct1)=sizeof(double)+sizeof(char)+sizeof(int)=13

但是當你在vc上執行如下測試**:

#includestruct

mystruct

;int

main()

執行結果為:16

其實,這是vc對變數儲存的乙個特殊處理。為了提高cpu的儲存速度,vc對一些變數的起始位址做了「對齊」處理。在預設情況下,vc

規定各成員變數存放的起始位址相對於結構的起始位址的偏移量必須為該變數的型別所占用的位元組數的倍數。下面列出常用型別的對齊方式(vc6.0,32位系統)。

型別            對齊方式(變數存放的起始位址相對於結構的起始位址的偏移量)

char              偏移量必須為sizeof(char)即1的倍數

int               偏移量必須為sizeof(int)即4的倍數

float             偏移量必須為sizeof(float)即4的倍數

double            偏移量必須為sizeof(double)即8的倍數

short             偏移量必須為sizeof(short)即2的倍數

各成員變數在存放的時候根據在結構中出現的順序依次申請空間,同時按照上面的對齊方式調整位置,空缺的位元組vc會自動填充。同時vc為了確保結構的大小為結構的位元組邊界數(即該結構中占用最大空間的型別所占用的位元組數)的倍數,所以在為最後乙個成員變數申請空間後,還會根據需要自動填充空缺的位元組。

現在來分析vc是怎樣來存放結構的:

struct

struct1

;

第乙個成員dda分配空間,其起始位址跟結構的起始位址相同(剛好偏移量0剛好為sizeof(double)的倍數),該成員變數占用sizeof(double)=8個位元組;接下來為第二個成員cda分配空間,這時下乙個可以分配的位址對於結構的起始位址的偏移量為8,是sizeof(char)的倍數,所以把cda存放在偏移量為8的地方滿足對齊方式,該成員變數占用 sizeof(char)=1個位元組;接下來為第三個成員ida分配空間,這時下乙個可以分配的位址對於結構的起始位址的偏移量為9,不是sizeof (int)=4的倍數,為了滿足對齊方式對偏移量的約束問題,vc自動填充3個位元組(這三個位元組沒有放什麼東西),這時下乙個可以分配的位址對於結構的起始位址的偏移量為12,剛好是sizeof(int)=4的倍數,所以把ida存放在偏移量為12的地方,該成員變數占用sizeof(int)=4個位元組;這時整個結構的成員變數已經都分配了空間,總的占用的空間大小為:8+1+3+4=16,剛好為結構的位元組邊界數(即結構中占用最大空間的型別所占用的位元組數sizeof(double)=8)的倍數,所以沒有空缺的位元組需要填充。所以整個結構的大小為:sizeof(struct1)=8+1+ 3+4=16,其中有3個位元組是vc自動填充的,沒有放任何有意義的東西。

下面再舉個例子,交換一下上面的struct1的成員變數的位置,使它變成下面的情況:

struct

mystruct2

;

在vc環境下,執行結果為:24

struct

mystruct2

;

所以該結構總的大小為:sizeof(struct2)為1+7+8+4+4=24。其中總的有7+4=11個位元組是vc自動填充的,沒有放任何有意義的東西。

cpoint

出處:

詳解C語言記憶體對齊

在c語言裡有乙個機制是記憶體對齊,當然不止c語言,包括其他的程式語言都會有記憶體對齊機制,否則編譯出來的軟體無法正常執行,至於為什麼呢?眾所周知,在記憶體中,所有的資料都是按位元組為最小單位儲存的,儲存單位稱為儲存單元,所以也叫記憶體是由很多儲存單元組成的,這些儲存單元 位元組 都有固定的位址標示著...

C語言 記憶體位元組對齊詳解

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

C語言記憶體對齊詳解(2)

vc對結構的儲存的特殊處理確實提高cpu儲存變數的速度,但是有時候也帶來了一些麻煩,我們也遮蔽掉變數預設的對齊方式,自己可以設定變數的對齊方式。vc 中提供了 pragma pack n 來設定變數以n位元組對齊方式。n位元組對齊就是說變數存放的起始位址的偏移量有兩種情況 第一 如果n大於等於該變數...