本文根據(jù)眾多互聯(lián)網(wǎng)博客內(nèi)容整理后形成,引用內(nèi)容的版權(quán)歸原始作者所有,僅限于學(xué)習(xí)研究使用,不得用于任何商業(yè)用途。
原則一:結(jié)構(gòu)體中元素是按照定義順序一個一個放到內(nèi)存中去的,但并不是緊密排列的。從結(jié)構(gòu)體存儲的首地址開始,每一個元素放置到內(nèi)存中時,它都會認(rèn)為內(nèi)存是以它自己的大小來劃分的,因此元素放置的位置一定會在自己寬度的整數(shù)倍上開始(以結(jié)構(gòu)體變量首地址為0計算)。
例一, 首先系統(tǒng)會將字符型變量a存入第0個字節(jié)(相對地址,指內(nèi)存開辟的首地址);然后在存放整形變量b時,會以4個字節(jié)為單位進(jìn)行存儲,由于第一個四字節(jié)模塊已有數(shù)據(jù),因此它會存入第二個四字節(jié)模塊,也就是存入到4~8字節(jié);同理,存放雙精度實型變量c時,由于其寬度為8,其存放時會以8個字節(jié)為單位存儲,也就是會找到第一個空的且是8的整數(shù)倍的位置開始存儲,此例中,此例中,由于頭一個8字節(jié)模塊已被占用,所以將c存入第二個8字節(jié)模塊。整體存儲示意圖如圖1所示。

考慮另外一個實例, 例二。
struct X
{
char a;
double b;
int c;
} S2;
在例二中僅僅是將double型的變量和int型的變量互換了位置。測試程序不變,測試結(jié)果卻截然不同,sizeof(S2)=24,不同于我們按照原則一計算出的8+8+4=20,這就引出了我們的第二原則。
原則二:在經(jīng)過第一原則分析后,檢查計算出的存儲單元是否為所有元素中最寬的元素的長度的整數(shù)倍,是,則結(jié)束;若不是,則補齊為它的整數(shù)倍。
例二中,我們分析完后的存儲長度為20字節(jié),不是最寬元素長度8的整數(shù)倍,因此將它補齊到8的整數(shù)倍,也就是24。這樣就沒問題了。其存儲示意圖如圖2所示。

掌握了這兩個原則,就能夠分析所有數(shù)據(jù)存儲對齊問題了。再來看幾個例子,應(yīng)用以上兩個原則來判斷。
例三:
struct X
{
double a;
char b;
int c;
} S3;
首先根據(jù)原則一來分析。按照定義的順序,先存儲double型的a,存儲在第0~7個字節(jié);其次是char型的b,存儲在第8個字節(jié);接下來是int型的c,順序檢查后發(fā)現(xiàn)前面三個四字節(jié)模塊都被占用,因此存儲在第4個四字節(jié)模塊,也就是第12~15字節(jié)。按照第一原則分析得到16個字節(jié),16正好是最寬元素a的寬度8的整數(shù)倍,因此結(jié)構(gòu)體變量S3所占存儲空間就是16個字節(jié)。存儲結(jié)構(gòu)如圖3所示。

例四:
struct X
{
double a;
char b;
int c;
char d;
} S4;
仍然首先按照第一原則分析,得到的字節(jié)數(shù)為8+4+4+1=17;再按照第二原則補齊,則結(jié)構(gòu)體變量S4所占存儲空間為24。存儲結(jié)構(gòu)如圖4所示:

例五:
struct X
{
double a;
char b;
int c;
char d;
int e;
} S5;
同樣結(jié)合原則一和原則二分析,可知在S4的基礎(chǔ)上在結(jié)構(gòu)體內(nèi)部變量定義最后加入一個int型變量后,結(jié)構(gòu)體所占空間并未增加,仍為24。存儲結(jié)構(gòu)示意圖如圖5所示。

例六:
如果將例五中加入的變量e放到第一個定義的位置,則情況就不同了。結(jié)構(gòu)體所占存儲空間會變?yōu)?2。其存儲結(jié)構(gòu)示意圖如圖6所示。
struct X
{
int e;
double a;
char b;
int c;
char d;
} S6;

補充:前面所介紹的都是元素為基本數(shù)據(jù)類型的結(jié)構(gòu)體,那么含有指針、數(shù)組或是其它結(jié)構(gòu)體變量或聯(lián)合體變量時該如何呢?
- 包含指針類型的情況。只要記住指針本身所占的存儲空間是4(8)個字節(jié)就行了,而不必看它是指向什么類型的指針。
- 結(jié)構(gòu)體作為成員。 如果一個結(jié)構(gòu)里有某些結(jié)構(gòu)體成員,則結(jié)構(gòu)體成員要從其內(nèi)部最大元素大小的整數(shù)倍地址開始存儲.(struct a里存有struct b,b里有char,int ,double等元素,那b應(yīng)該從8的整數(shù)倍開始存儲.)
參考文檔
結(jié)構(gòu)體在內(nèi)存中的對齊規(guī)則
結(jié)構(gòu)體在內(nèi)存中的對齊規(guī)則
版權(quán)聲明:本文為CSDN博主「QuitePig」的原創(chuàng)文章,遵循CC 4.0 BY-SA 版權(quán)協(xié)議,轉(zhuǎn)載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/QuitePig/article/details/7908786