結構體對齊問題

2021-04-13 09:33:15 字數 1801 閱讀 8538

1,比如:

structa;

structb;

sizeof( a)=6, sizeof( b)=8,為什麼?

注:sizeof(short)=2,sizeof(long)=4

因為:「成員對齊有乙個重要的條件,即每個成員按自己的方式對齊.其對齊的規則是,每個成員按其型別的對齊引數(通常是這個型別的大小)和指定對齊引數(這裡預設是8位元組)中較小的乙個對齊.並且結構的長度必須為所用過的所有對齊引數的整數倍,不夠就補空位元組.」(引用)

結構體a中有3個short型別變數,各自以2位元組對齊,結構體對齊引數按預設的8位元組對齊,則a1,a2,a3都取2位元組對齊,則sizeof(a)為6,其也是2的整數倍;

b中a1為4位元組對齊,a2為2位元組對齊,結構體預設對齊引數為8,則a1取4位元組對齊,a2取2位元組對齊,結構體大小6位元組,6不為4的整數倍,補空位元組,增到8時,符合所有條件,則sizeof(b)為8;

可以設定成對齊的

#pragma pack(1)

#pragma pack(push)

#pragma pack(1)

structa;

structb;

#pragma pack(pop)        結果為sizeof( a)=6,sizeof( b)=6

************************

2,又如:

#pragma pack(8)

struct s1;

struct s2 ;

#pragma pack()

sizeof(s2)結果為24.

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

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

a      b

s1的記憶體布局:1***, 1111,

c      s1.a    s1.b         d

s2的記憶體布局:1***, 1***,   1111, ****11111111

這裡有三點很重要:

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

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

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

補充一下,對於陣列,比如:

char a[3];這種,它的對齊方式和分別寫3個char是一樣的.也就是說它還是按1個位元組對齊.

如果寫: typedef char array3[3];

array3這種型別的對齊方式還是按1個位元組對齊,而不是按它的長度.

不論型別是什麼,對齊的邊界一定是1,2,4,8,16,32,64....中的乙個.

結構體對齊問題

昨天華為面試,問到了關於結構體對齊的問題。我懵逼了,結構體對齊是什麼梗?一開始還以為是和資源受限的裝置 微控制器啊之類的嵌入式裝置 開發有關。今天下了下資料,發現原理是真的簡單,當時多考慮一會應該能想出來的。struct struct a 在計算機記憶體中,結構體變數的儲存通常是按字長對齊的,比如8...

結構體位元組對齊問題

結構體 struct 的sizeof值,並不是簡單的將其中各元素所佔位元組相加,而是要考慮到儲存空間的位元組對齊問題。先看下面定義的兩個結構體.struct s1 struct s2 分別用程式測試得出sizeof s1 6 sizeof s2 4 可見,雖然兩個結構體所含的元素相同,但因為其中存放...

結構體的大小 結構體對齊問題

c語言中,基本資料型別與作業系統有關 雖然直接與編譯器相關 基本沒有什麼變化。比如在32位作業系統中,int佔4個位元組,long佔4個位元組,char佔1個位元組,double佔8個位元組。但是結構體的大小並不只與作業系統有關了,與編譯器有比較大的關係。不同的編譯器有不同的對齊方式,下面以32為l...