為了能使cpu對變數進行高效快速的訪問,變數的起始位址應該具有某些特性,
即所謂的「對齊」。例如對於4位元組的int型別變數,其起始位址應位於4位元組邊界上,
即起始位址能夠被4整除。變數的對齊規則如下(32位系統):
type
alignment
char
在位元組邊界上對齊
short (16-bit)
在雙位元組邊界上對齊
int and long (32-bit)
在4位元組邊界上對齊
float
在4位元組邊界上對齊
double
在8位元組邊界上對齊
2) 結構體每個成員相對於結構體首位址的偏移量都是成員大小的整數倍,如有需要編譯器會在成
員之間加上填充位元組;例如上面第二個結構體變數的位址空間。
3) 結構體的總大小為結構體最寬基本型別成員大小的整數倍,如有需要編譯器會在最末乙個成員
之後加上填充位元組。
例如:struct s1
;在上述結構體中,size最大的是short,其長度為2位元組,因而結構體中的char成員a、c都以2
為單位對齊,sizeof(s1)的結果等於6;
a b c
s1的記憶體布局 1* 11 1* (*表示填充的位元組,下同)
若改為struct s1
;其結果顯然為12。
a b c
s1的記憶體布局 1*** 1111 1***
2.又如:
struct s1;
struct s2 ;
sizeof(s2)結果為24;
分析如下:
根據上面的分析sizeof(s1)=8;
s1的記憶體布局 a b
1*** 1111
s2 中,c和s1中的a一樣,按1位元組對齊,而d 是個結構,它是8個位元組,它按什麼對齊呢?對
於結構來說,它的預設對齊方式就是它的所有成員使用的對齊引數中最大的乙個,s1的就是4.所以,
成員d就是按4位元組對齊.成員e是8個位元組,它是預設按8位元組對齊,和指定的一樣,所以它對到8位元組
的邊界上,這時, 已經使用了12個位元組了,所以又新增了4個位元組的空,從第16個位元組開始放置成員
e.這時,長度為24,已經可以被8(成員e按8位元組對齊)整除.這樣, 一共使用了24個位元組.
s2的記憶體布局 c d e
1*** 1***1111**** 11111111
再看兩個結構體成員比較複雜的例子:
typedef struct student
char name[10];
long sno;
char ***;
float score [4];
} stu;
sizeof(stu)=?
stu的記憶體布局 name sno *** score
1111111111** 1111 1*** 1111111111111111
sizeof(stu)=10+2+4+1+3+16
如果我們把stu中的成員改一下順序:
typedef struct student
char name[10];
char ***;
long sno;
float score [4];
} stu;
stu的記憶體布局 name *** sno score
1111111111 1* 1111 1111111111111111
sizeof(stu)=10+2+4+16
注意:1) 對於空結構體,sizeof == 1;因為必須保證結構體的每乙個例項在記憶體中都
有獨一無二的位址。
2) 結構體的靜態成員不對結構體的大小產生影響,因為靜態變數的儲存位置與
結構體的例項位址無關。
例如:
struct t;
sizeof(t) == 1;
struct t1;
sizeof(t1) == 1;
位元組對齊的問題
位元組對齊的細節和具體編譯器實現相關,表現為具體的彙編翻譯可能會因為編譯器的不同而不同,但一般而言,滿足三個準則 1 結構體變數的首位址能夠被其最寬基本型別成員的大小所整除 2 結構體每個成員相對於結構體首位址的偏移量都是成員大小的整數 倍,如有需要編譯器會在成員之間加上填充位元組 例如上面第二個結...
位元組對齊的問題
基本概念 位元組對齊 計算機儲存系統中以byte為單位儲存資料,不同資料型別所佔的空間不同,如 整型 int 資料佔4個位元組,字 符型 char 資料佔乙個位元組,短整型 short 資料佔兩個位元組,等等。計算機為了快速的讀寫資料,預設情況下將資料存放在某個位址的起始位置,如 整型資料 int ...
位元組對齊問題
現代計算機中記憶體空間都是按照byte劃分的,從理論上講似乎對任何型別的變數的訪問可以從任何位址開始,但實際情況是在訪問特定型別變數的時候經常在特 定的記憶體位址訪問,這就需要各種型別資料按照一定的規則在空間上排列,而不是順序的乙個接乙個的排放,這就是對齊。對齊的作用和原因 各個硬體平台對儲存空間的...