結構體變數記憶體對齊遵循以下三個原則:
1、變數的起始位址能夠被其對齊值整除,結構體變數的對齊值為最寬的成員大小;
2、結構體每個成員相對於起始位址的偏移能夠被其自身對齊值整除,如果不能則在前乙個成員後面補充位元組;
3、結構體總體大小能夠被最寬的成員大小整除,如不能則在後面補充位元組。
此外還有編譯器的預設對齊值,一般預設對齊值為4(結構體的實際對齊值會取結構體對齊值和編譯器預設對齊值中較小的那乙個)。
那麼為什麼要記憶體對齊?
1. 為了減少記憶體的使用;
2. 為了提公升資料讀取的效率
以下面結構體為例:
struct test
;
c++中可以使用alignof獲取型別的對齊值,char型別的對齊值為1, int的對齊值為4, short的對齊值為2,整個結構體的對齊值為4。假設結構體變數的起始位址已經對齊,那麼結構體的第乙個成員a已經對齊,由於第乙個成員a的大小為1而第二成員b的對齊值為4,則根據第二條對齊原則需要在第乙個成員後填充3個位元組才能使第二個成員對齊,第二個成員對齊後第三個成員的起始位址剛好為其對齊值的整數倍所以不需要進行填充,此時算上填充位元組,結構體占用的總位元組為10位元組,又由第三條原則,結構體大小需要為4的整數倍,因此需要在第三個成員c後填充2個位元組,可以算得結構體的總大小為12(在預設對齊值為2時,大小為8位元組)。
改變結構體成員順序如下:
struct test
;
改變成員順序後,若結構體變數的起始位址已經對齊,則根據原則2三個成員均以對齊,中間不需要進行填充,此時結構體占用的總位元組為7,又由原則3需要在最後乙個變數後填充1個位元組,因此結構體總大小為8(在預設對齊值為2時,大小也為8位元組)。
從上面的例子可以看出根據對齊原則合理安排結構體成員的順序可以減少記憶體的占用。
現在考慮乙個double型別的陣列(double型別為8位元組對齊), 其在記憶體中所處的位置如下:
陣列的首位址為2,根據原則1陣列未對齊。若cpu每次從記憶體中為8位元組整數倍的位址開始讀入8位元組的資料,則每次從未對齊的陣列中讀取乙個成員都要進行兩次讀取操作,而從對齊的陣列中讀取則只需要一次讀取操作,陣列對齊時讀取效率有較大提公升(雖然現在也有很多處理器支援非對齊的讀取,但是還是推薦對齊)。
C 記憶體對齊
vc6.0編譯器對記憶體對齊的管理方式遵循以下兩個原則 1.對於結構體內部變數的對齊方式 變數存放的起始位址相對於結構的起始位址的偏移量 char 偏移量必須為sizeof char 即1的倍數 int 偏移量必須為sizeof int 即4的倍數 float 偏移量必須為sizeof float ...
c 記憶體對齊
一.計算struct的size有兩個原則 pragma pack n n是編譯器的對齊位元組數 1 struct中各成員按照對齊原則 在為當前變數 設為a 分配記憶體時,要參考之前所有變數的偏移量之和 設為d d必須是min n,sizeof a 的倍數,否則編譯器會自動在最後補上缺少的位元組數。2...
C 記憶體對齊
c 中的記憶體對齊 記憶體對齊 在我們的程式中,資料結構還有變數等等都需要占有記憶體,在很多系統中,它都要求記憶體分配的時候要對齊,這樣做的好處就是可以提高訪問記憶體的速度。我們還是先來看一段簡單的程式 程式一 1 include 2 using namespace std 3 4structx1 ...