原文出處:【點擊,進入原文頁面】
今天在看結構體和共用體部分的時候,遇到了一個新名詞“內存對齊”。先引入問題吧。如下:
struct student
{
char name[20];
int age;
char sex;
char phone[15];
};
struct student p1;
sizeof(p1)=?
這個很簡單得出答案,即20+4+1+15=40Byte。如果將phone[15]改爲phone[16],結果是44。難道不是41嗎?
這裏便要引入內存對齊的概念。內存爲了提高訪問效率,便規定以結構體中最大的基本單位長度爲對齊標準。即實際分配的內存大小是對齊標準的整數倍(必要條件)。在上面的結構體中,最大的基本類型是int。因此以4Byte爲對其標準。所以實際內存大小應該爲4的整數倍,即爲44Byte.
也許你有疑惑:name[20]不是要20Byte嗎,爲什麼以4Byte爲對齊標準?請注意這裏的基本類型。name[20]是一個字符串數組,數組屬於複合的數據類型。複合的數據類型還有結構體,共用體。基本的數據類型是整型,字符型,浮點型。如果你還有不解,那麼看下題:
struct score
{
float english;
float math;
float computer;
};
struct student
{
char name[10];
int age;
char sex;
struct score st_score;
};
在student結構體中含有數據類型爲struct score這樣的變量。struct score的大小爲12Byte,也是struct student結構體中最大的數據類型,但是我們的對齊標準是4Byte,就如我們剛說的那樣,內存的對齊標準是取結構體中最大的基本數據類型,這裏我們取sizeof(int)。
再看下面的問題:
union data1
{
int i;
char c;
char str[9];
};
struct data2
{
int i;
char c;
char str[9];
};
sizeof(struct data1)=? sizeof(struct data2)=?
對於前者,由於共用體的存儲大小由最大的成員來決定,因此上題中共用體的存儲大小爲9Byte,考慮到內存對齊,它以sizeof(int)=4Byte來對齊,因此實際內存分配大小是12Byte。對於後者,存儲大小是4+1+9=14Byte,這個結構體以4對齊,因此實際分配大小爲16Byte。
現在你應該對於共用體和結構體的內存對齊有所瞭解了。那麼再接着往下看:
struct data
{
char c;
double d;
char ch;
}
sizeof(struct data)=?
有了上面的理解,10肯定不會是答案,那麼會是16吧。也錯。正確答案是24。你可能會感到莫名其妙:按照上面所說的方法,以8爲對齊標準,那麼10不是8的倍數,那就是16呀。爲什麼呢?請你耐心看下面。
首先我們知道結構體變量是分配的連續內存空間。d毫無疑問是分配8Byte,對於d“前面”的c,按照對齊標準我們應該分配8Byte,而d後面的ch,按照對齊標準也應該分配8Byte。因此結果是24。
如果這樣:
struct data
{
double d;
char c;
char ch;
}
sizeof(struct data)=16。
因爲內存沒必要分別爲c和ch分配8Byte來進行對齊,將它們放在一個8byte裏就可以實現內存對齊。上面在引入內存對齊概念的時候,我用括號特別註釋必要條件便是說明此處內容。