Intel和微軟同時出現的面試題

才智咖 人氣:3.17W
Intel和微軟同時出現的面試題
#pragma pack(8)
struct s1
{
short a;
long b;
};
struct s2
{
char c;
  s1 d;
  long long e;
};
#pragma pack()

問:
of(s2) = ?
2.s2的c後面空了幾個位元組接著是d?


答案:

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的記憶體佈局:11**,1111,
                          c    S1.a S1.b     d
S2的記憶體佈局:1***,11**,1111,****11111111

這裡有三點很重要:
1.每個成員分別按自己的方式對齊,並能最小化長度
2.複雜型別(如結構)的預設對齊方式是它最長的成員的對齊方式,這樣在成員是複雜型別時,可以最小化長度
3.對齊後的長度必須是成員中最大的對齊引數的整數倍,這樣在處理陣列時可以保證每一項都邊界對齊

補充一下,對於陣列,比如:
char a[3];這種,它的對齊方式和分別寫3個char是一樣的.也就是說它還是按1個位元組對齊.
如果寫: typedef char Array3[3];
Array3這種型別的對齊方式還是按1個位元組對齊,而不是按它的長度.
不論型別是什麼,對齊的邊界一定是1,2,4,8,16,32,64....中的一個.