天天看點

C語言結構體的對齊原則

q:關于結構體的對齊,到底遵循什麼原則?

a:首先先不讨論結構體按多少位元組對齊,先看看隻以1位元組對齊的情況:

C語言結構體的對齊原則
C語言結構體的對齊原則

輸出:

sizeof(student) is 7

offset(student,sex) is 0

offset(student,score) is 1

offset(student,age) is 3

可以看到,如果按1位元組對齊,那麼結構體内部的成員緊密排列,sizeof(char) == 1, sizeof(short) == 2, sizeof(int) == 4.

修改上面的代碼, 去掉#pragma pack語句,代碼如下:

C語言結構體的對齊原則
C語言結構體的對齊原則

運作結果:

sizeof(student) is 8

offset(student,score) is 2

offset(student,age) is 4

此時,各個成員之間就不像之前那樣緊密排列了,而是有一些縫隙。這裡需要介紹下對齊原則:

此原則是在沒有#pragma pack語句作用時的原則(不同平台可能會有不同):

原則a:struct或者union的成員,第一個成員在偏移0的位置,之後的每個成員的起始位置必須是目前成員大小的整數倍;

原則b:如果結構體a含有結構體成員b,那麼b的起始位置必須是b中最大元素大小整數倍位址;

原則c:結構體的總大小,必須是内部最大成員的整數倍;

依據上面3個原則,我們來具體分析下: sex在偏移0處,占1位元組;score是short類型,占2位元組,score必須以2的整數倍為起始位置,是以它的起始位置為2; age為int類型,大小為4位元組,它必須以4的整數倍為起始位置,因為前面有sex占1位元組,填充的1位元組和score占2位元組,位址4已經是4的整數倍,是以age的位置為4.最後,總大小為4的倍數,不用繼續填充。

繼續修改上面的代碼,增加#pragma pack語句:

C語言結構體的對齊原則
C語言結構體的對齊原則

具體分析下:

有了#pragma pack(4)語句後,之前說的原則a和c就不适用了。實際對齊原則是自身對齊值(成員sizeof大小)和指定對齊值(#pragma pack指定的對齊大小)的較小者。依次原則,sex依然偏移為0, 自身對齊值為1,指定對齊值為4,是以實際對齊為1; score成員自身對齊值為2,指定對齊值為4,實際對齊為2;是以前面的sex後面将填充一個1位元組,然後是score的位置,它的偏移為2;age自身對齊值為4,指定對齊為4,是以實際對齊值為4;前面的sex和score正好占用4位元組,是以age接着存放;它的偏移為4.

q:關于位域的問題,空域到底表示什麼?

a:它表示之後的位域從新空間開始。

C語言結構體的對齊原則
C語言結構體的對齊原則

sizeof(bit_info) is 8

bit_info中的a, b占用4個位元組的前4位,到int:0; 時表示此時将填充餘下所有沒有填充的位,即剛剛的4個位元組的餘下28位;int d:2; 将從第四個位元組開始填充,又會占用4個位元組,是以總大小為8.

本文版權歸作者和部落格園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接配接,否則保留追究法律責任的權利。

http://www.cnblogs.com/luxiaoxun/archive/2012/11/09/2762438.html

繼續閱讀