前段時間參加乙個模擬面試的時候碰到過乙個記憶體對齊的選擇題,我本來一直以為我對這一塊理解的很好,不過最後卻掛掉了。
總結下來,就兩個原則:
1:大小為size的子段,它的結構體內偏移offset需要符合offset mod size==0
2:整個結構體的大小必須為結構體內最大字段型別的整數倍
3:即使有結構體巢狀,內層結構體也需要和最長的標量對齊
可能說的有點模糊,不過下面我舉幾個例子你就明白了。看下面一段**:
#include
#include
struct ****1ex1;
struct ****2ex2;
struct ****3ex3;
struct ****4ex4;
struct ****5ex5;
int main(void)
我先把執行結果貼出來,然後乙個乙個對應我前面提到的3個原則進行分析。執行結構如下(64位機器上指標大小為8byte):
在我的機器上size大小為4
ok,先看第乙個24位元組
struct ****1ex1;
ok,先看第一句話:偏移量offset必須滿足offset%4==0。假如說ex1起始位址為0,那麼c的起始位置就必須為12,而不是a+b=8byte+1byte=9,因為要滿足offset%4==0。
為什麼要滿足這一點呢?這個說起來其實很麻煩,不過核心就一句話 ,為了提高io的訪問速度。假使說ex1中變數的分布如下:
double a //address 0-7
char b //address 8
int c //9-12
short d //13-14
上述是沒有記憶體對齊的情況,c的起始位址為9,那麼這樣機會出現麻煩,cpu需要進行兩次io操作才能把c中的資料讀完。因為cpu的size為4,所以只能先讀取8-11,然後12-15。所以如果我們在這裡填充一下,如下;
double a //address 0-7
char b //address 8-11
int c //address 12-15
short
//address 16-20
現在看第二個例子:
struct ****2ex2;
ex2的大小實際為8,這個時候可能有人會認為整個結構體大小為12了,因為為每個都要滿足offset%4==0啊,讓我們再仔細考慮以下,char和short分別為1byte和2byte,所以a和b的大小總共為3byte,因為我乙個字長為4byte,所以這兩個就不要對齊了,反正我能一直把他們讀完。
所以他們的真實情況是下面這樣的:
char a //address 0
//這裡填充了1byte,因為規定short型別的起始位址必須為偶數
short b //address 2-3
int c //address 4-7
下面看第三個例子:
struct ****3ex3;
ex3的大小為24位元組,因為還要滿足整個結構體的大小必須為結構體內最大子段的整數倍。ex3中最大子段大小為int*p,為8位元組,所以整個結構體大小為24位元組,而不是4(a)+4(b)+4(c)+8(p)=20位元組。
現在看最後乙個例子:
struct ****4ex4;
struct ****5ex5;
這個大小為32位元組,而不是36位元組,雖然整個結構體內最大欄位ex4大小為12位元組 ,不過它要滿足第三個原則。即使有結構體巢狀,它也要和最大欄位也就是double a對齊。因此它的實際分布是下面這樣:
****4 ivec //0-15
double a //16-23
int b //24-27
char c //27-31
而實際上執行結果中的最後兩行,也證明了我們的猜想。
以上就是全部內容:
參考資料:
關於記憶體對齊
資料傳送到網路板的資料報大小根本不是實際控制數 據包的大小 這時我才想起乙個人,stanley b.lippman,他寫的那 一本書 inside object modale 曾經提過這樣的事 情,編譯器為了提高cpu的效率,會對struct 的結構進行優化,利用sizeof 可以得出不同的計算機上...
關於記憶體對齊
早上看了乙個貼的面試題,struct st int i short s char c sizeof struct st 是多少?int 4,short 2,char 1,但是sizeof st 是8。這個就是記憶體對齊 再來看個例子 struct strt1 strt1 s1 假設s1.c1位址為0...
關於記憶體對齊
資料傳送到網路板的資料報大小根本不是實際控制資料報的大小 這時我才想起乙個人,stanley b.lippman,他寫的那一本書 inside object modale 曾經提過這樣的事情,編譯器為了提高cpu的效率,會對struct 的結構進行優化,利用sizeof 可以得出不同的計算機上對 s...