內存對齊,大端字節 序小端字節序驗證

空結構體:對於空結構體,就是隻有結構體這個模子,但裏面卻沒有元素的結構體。數組

例:ide

typedef struct studenturl

{spa

}std;blog

這種空結構體的模子佔一個字節,sizeof(std)=1。內存


柔性數組:get

結構體中最後一個元素能夠是一個大小未知的數組,稱做柔性數組成員,規定柔性數組前面至少有一個元素.it

typedef struct studentio

{class

int i;

char arr[];     //柔性數組成員

}std;

sizeof(std)=4;

sizeof求取該結構體大小是不包含柔性數組的大小,柔性數組無論有沒有大小都不計入結構體的大小,能夠經過動態內存爲它實現內存分配。


spacer.gifwKioL1cXmTvSNbgWAAAdDRZ4IbM189.png

內存對齊:

對於字(天然邊界是偶數地址),雙字(天然邊界是能被4整除的地址),四字(天然邊界是能被8整除的地址)自己就是對齊的。爲何要對齊呢?這是由於對於對齊的內存只須要一次內存訪問,對於未對齊的內存,處理器要兩次內存訪問。

spacer.gifwKiom1cXmLSTAm61AABfuRzGn-Q952.png

未對齊:一個字或者雙字跨越了4字節邊界,或者雙字跨越了8字節邊界,須要兩次內存訪問。


對於結構體,聯合體在計算其大小時要考慮其內存對齊,以結構中所佔字節數最大的類型類型對齊。

例:

struct test

{

    char a1;

    short b2;

    char  c3;

    int d4;

};

由於其中int類型所佔字節最多,因此以4字節對齊,內存分配方式以下,總共佔12個字節:

spacer.gifwKioL1cXmZuR9_YbAAAhDiVhUew706.png

分析:由於以4字節對齊,首先char a1佔一個字節存到00處,short b2 是字佔兩個字節 ,以偶數地址對齊,因此不能直接存到01 02 上,而應該存到02 03上,而空出來的01就會被浪費掉。同理,當char c3存到04上後,對於int i,雙字必需要存到4的倍數的地址上,就只能存到08 09 0a 0b上,空出來的05 06 07會被浪費掉。


struct test

{

    char a1;

    char  c3;

    short b2;  

    int d4;

};

一樣的,以4字節對齊,總共佔8個字節:

這是由於a1存到00,c3存到01,b2恰好存到02 03上,以偶數地址對齊,d4也恰好從04開始存儲,以4字節對齊,沒有浪費內存。



大端字節序:高字節存儲在低地址,低字節存儲在高字節處

小端字節序:低字節存儲在低地址,高字節存儲在高地址處

計算機的最小存儲單位是字節,一個字節佔8bit位。

以int爲例:

例如:1的二進制碼是 

00000000 00000000 00000000 00000001

寫成十六進制形式 :00 00 00 01這就表明了4個字節,而內存是從低地址到高地址的,這樣就產生了兩種存儲方式。

spacer.gifwKioL1cXmcfxKORtAAA805lwhxU219.png

由於存儲方式方式的不一樣,讀取時也就產生了兩種方式。

通常讀取是從低地址向高地址讀取,爲了將存儲與讀取統一取來,因此採用小端存儲,這樣的話,低字節存到低地址,高字節存到高地址。

驗證方法:

一、能夠聲明一個int a=1,再聲明一個char *p=&a;由於a佔4個字節,char *一次向後訪問一個字節,因此若是是小端的話在電腦上輸出*p應該是1.

二、也能夠用union,由於union是內存公用,因此聲明一個int a,char c;對a賦值爲1,輸出c觀察結果。

有些問題若是不考慮大小端的話是根本想不明白的。

相關文章
相關標籤/搜索