c語言記憶體對齊(2)

2021-06-22 02:53:15 字數 1619 閱讀 5037

**:

vc對結構的儲存的特殊處理確實提高cpu儲存變數的速度,但是有時候也帶來了一些麻煩,我們可以遮蔽掉變數預設的對齊方式,自己設定變數的對齊方式。vc 中提供了

#pragma pack(n)來設定變數以n位元組對齊方式。n位元組對齊就是說變數存放的起始位址的偏移量有兩種情況: 第

一、如果n大於等於該變數所占用的位元組數,那麼偏移量必須滿足預設的對齊方式; 第

二、如果n小於該變數的型別所占用的位元組數,那麼偏移量為n的倍數,不用滿足預設的對齊方式。

結構的總大小也有個約束條件,分下面兩種情況:如果n大於所有成員變數型別所占用的位元組數,那麼結構的總大小必須為占用空間最大的變數占用的空間數的倍數;否則必須為n的倍數。下面舉例說明其用法:

#pragma pack(push) //

儲存對齊狀態

#pragma pack(4)//

設定為4位元組對齊

struct

test

; #pragma pack(pop)//

恢復對齊狀態

以上結構的大小為16,下面分析其儲存情況,首先為m1分配空間,其偏移量為0,滿足我們自己設定的對齊方式(4位元組對齊),m1占用1個位元組。接著開始為m4分配空間,這時其偏移量為1,需要補足3個位元組,這樣使偏移量滿足為n=4的倍數(因為sizeof(double)大於n),m4占用8個位元組。接著為m3分配空間,這時其偏移量為12,滿足為4的倍數,m3占用4個位元組。這時已經為所有成員變數分配了空間,共分配了4+8+4=16個位元組,滿足為n的倍數。如果把上面的#pragma pack(4)改為#pragma pack(16),那麼我們可以得到結構的大小為24。

再看下面這個例子:

#pragma pack(8)

struct

s1;struct

s2 ;

#pragma pack()

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

也就是說上面雖然指定了按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位元組對齊)整除.這樣,sizeof(s2)為24個位元組.

這裡有三點很重要:

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

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

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

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

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

C語言練習 2 記憶體對齊

預設情況下,編譯器預設將結構體 棧中的成員資料進行記憶體對齊。編譯器將未對齊的成員向後移,將每乙個都成員對齊到自然邊界上,從而也導致了整個結構的尺寸變大。我們經常會接觸到結構體,合理的設定結構體成員能做到節約記憶體的目的。例子1 include struct test1 struct test2 i...

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

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