struct s1
;
struct s1
;
正常情況下應該是這樣儲存的,但是我們說過,cpu只能從特定的地方訪存。現在我們假設cpu只能從4的倍數處訪問記憶體。訪問char c1的時候從0(這裡的0指的是相對於結構體起始位址的偏移量,後續0位址均指偏移位址)位址處訪問;訪問int i的時候它只能先訪問四個位元組然後捨棄第乙個位元組,在訪問第最後乙個位元組,然後把兩個片段拼接起來。這樣的話cpu就要訪問兩次記憶體,導致效率低下。
而如果我們這樣儲存,捨棄掉中間三個位元組,cpu在訪問int i時就可以一次訪問完成。
現在我們再來看一下這個例子
在記憶體中的實際儲存情況就是這樣子的。這樣的話佔了9個位元組,但是結構體的大小要能整除成員中最大的對齊數。s1中最大的對齊數是4,從9往後可以整除4的就是12了,所以s1結構體的大小為12位元組。
再看一下這個例子
struct s1
;struct s2
;
這裡s1中,c1在0位址處儲存,a[3]對齊數為4,從4號位址開始存,佔12個位元組。c2對齊數為1,緊挨著a[3],存在16號位址,總共佔17個位元組,但是結構體大小要能整除自身最大對齊數,所以最終大小為20個位元組。
s2中c1還是存在0位址處,第二個元素是結構體,根據定義對齊數為自身成員最大對齊數4,從4號位址開始存,佔20個位元組。c2存在24號位址,總共佔25個位元組,保證整除自身最大對齊數,最終大小為28個位元組。
#pragma pack(4)
struct s1
;#pragma pack()
struct s2
;
#pragma pack()這條語句就是修改預設對齊數的,這裡我們先將預設對齊數修改為4,當s1編譯後在恢復預設,所以在儲存時,s1的預設對齊數是4,s2的預設對齊數是8(vs環境下)。
c語言中,除了結構體,還有聯合也要注意記憶體對齊。
C語言學習(四) 記憶體(位元組對齊與記憶體的種類)
位元組對齊 struct dat sizeof dat 8 利用空間換取效率,給char a 分配四個位元組大小的空間 編譯器在讀取的時候一次讀取四個位元組,取出結構體中的內容 與定義的順序有關 struct dat struct dat1 sizeof dat 8 給char a 分配四個位元組之...
c語言學習筆記之記憶體分割槽
c語言有五大記憶體分割槽,分別是棧,堆,全域性區,常量區,區。棧 在需要的時候由編譯器 系統 自動分配,在不需要的時候會由系統自動 的儲存區,記憶體由系統管理,函式中定義的變數儲存在棧中,當呼叫函式的時候函式中定義的變數會被加到棧中,當函式離開的時候,被新增的變數會從棧中移除,棧在最高的位址上,所以...
C語言學習 記憶體分割槽
1.1 資料型別 對函式返回的限定 void fun int a 對函式引數的限定 int fun void void a error,不能確定分配記憶體空間的大小void p ok,萬能指標,指標型別都是4個位元組,函式引數,函式有返回值 1.void 可以指向任何型別的資料,被稱為萬能指標 vo...