字節對齊問題(struct中)

原文出處:【點擊,進入原文頁面】

今天在看結構體和共用體部分的時候,遇到了一個新名詞“內存對齊”。先引入問題吧。如下:

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裏就可以實現內存對齊。上面在引入內存對齊概念的時候,我用括號特別註釋必要條件便是說明此處內容。


發佈了67 篇原創文章 · 獲贊 1099 · 訪問量 40萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章