為了能使cpu對變數進行高效快速的訪問,變數的起始位址應該具有某些特性,
即所謂的「對齊」。例如對於4位元組的int型別變數,其起始位址應位於4位元組邊界上,
即起始位址能夠被4整除。變數的對齊規則如下(32位系統):
type
alignment
char
在位元組邊界上對齊
short (16-bit)
在雙位元組邊界上對齊
int and long (32-bit)
在4位元組邊界上對齊
float
在4位元組邊界上對齊
double
在8位元組邊界上對齊
位元組對齊的細節和具體編譯器實現相關,但一般而言,滿足三個準則:
1) 結構體變數的首位址能夠被其最寬基本型別成員的大小所整除;
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
stu;
sizeof(stu)=?
stu的記憶體布局 name sno *** score
1111111111** 1111 1*** 1111111111111111
sizeof(stu)=10+2+4+1+3+16
如果我們把stu中的成員改一下順序:
typedef struct student
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;
位元組對齊問題
現代計算機中記憶體空間都是按照byte劃分的,從理論上講似乎對任何型別的變數的訪問可以從任何位址開始,但實際情況是在訪問特定型別變數的時候經常在特 定的記憶體位址訪問,這就需要各種型別資料按照一定的規則在空間上排列,而不是順序的乙個接乙個的排放,這就是對齊。對齊的作用和原因 各個硬體平台對儲存空間的...
位元組對齊問題
1 什麼是位元組對齊問題?一般來說,計算機按照其字長方式來定址可以提高執行效率,比如32位 4位元組 的x86 結構下,如果每次訪問的變數其位址都是4的倍數,則每次對變數的訪問只需要一次匯流排 操作。因此,編譯器為了迎合cpu的這一特性,一般在編譯的時候都會對變數的儲存方式 進行對齊處理。當然x86...
位元組對齊問題
位元組序問題關係到資料結構設計的是否合理,合理的資料結構設計可以節省記憶體空間,同時還能夠提高資料訪問效率,這在資源有限的其嵌入式系統中是非常重要的.我們可以先看看這兩個例子就大概了解了位元組對齊的問題了。在pc機上char是佔1個位元組,而int是4個位元組。include include voi...