3.預習結構體大小計算【結構體內存對齊】。
1)結構體為什麼要記憶體對齊(也叫位元組對齊):
結構體是一些資料的集合。結構體位址其實就是結構體第乙個元素的位址。如果結構體各個元素之間不存在記憶體對齊問題,他們都挨著排放的。對於32位機,32位編譯器(這是目前常見的環境,其他環境也會有記憶體對齊問題),就很可能操作乙個問題:當你想要去訪問結構體中的乙個資料的時候,需要你操作兩次資料匯流排,因為這個資料卡在中間,如圖:
在上圖中,對於第2個short資料進行訪問的時候,在32位機器上就要操作兩次資料匯流排。這樣會非常影響資料讀寫的效率,所以就引入了記憶體對齊的問題。
a)平台原因:不是所有的硬體平台都能訪問任意位址上的任意資料的;某些硬體平台只能在某些位址處取某些特定型別的資料,否則丟擲硬體異常。
b)效能原因:資料結構(尤其是棧)應該盡可能地在自然邊界上對齊。
原因在於,為了訪問未對齊的記憶體,處理器需要作兩次記憶體訪問;而對齊的記憶體訪問僅需要一次訪問。
3)結構體內存對其規則:
a.第乙個成員在與結構體變數偏移量為0的位址處。
b.其他成員變數要對齊到某個數字(對齊數)的整數倍的位址處。
//對齊數 = 編譯器預設的乙個對齊數與該成員大小的較小值。
vs中預設的值為8
linux中的預設值為4
c.結構體總大小為最大對齊數(每個成員變數除了第乙個成員都有乙個對齊數)的整數倍。
d.如果巢狀了結構體的情況,巢狀的結構體對齊到自己的最大對齊數的整數倍處,結構體的整體大小就是所有最大對齊數(含巢狀結構體的對齊數)的整數倍。
例1:4個位元組對齊分析
str1的記憶體分布:(圈代表記憶體空著,叉號代表被占用)注意:按照4位元組對齊
str2的記憶體分布:
由上圖可知,str1為12個位元組,str2為8個位元組。
例2:8個位元組對齊分析
#include
struct test1
test1;
struct test2
test2;
int main()
先看結構體test1
a) c是char型別,按1個位元組對齊
b) i是int型別,按四個位元組對齊,所以在c和i之間實際上空了三個位元組。
整個結構體一共是1 + 3(補齊)+ 4 = 8位元組。
再看test2
a)i是int型別,按4位元組對齊
b)d是double型別,按8位元組對齊,所以i和d之間空了4位元組
c)c是char型別,按1位元組對齊。
所以整個結構體是 4(i)+ 4(補齊)+ 8(d) +1(c) = 17位元組,注意!還沒完,整個結構體還沒有對齊,因為結構體中空間最大的型別是double,所以整個結構體按8位元組對齊,那麼最終結果就是17 + 7(補齊) = 24位元組。
注意:一般來說,結構體的對齊規則是先按資料型別自身進行對齊,然後再按整個結構體進行對齊,對齊值必須是2的冪,比如1,2,4,8,16。如果乙個型別按n位元組對齊,那麼該型別的變數起始位址必須是n的倍數。比如int按四位元組對齊,那麼int型別的變數起始位址一定是4的倍數,比如 0x0012ff60,0x0012ff48等。
例3:結構體中巢狀結構體的記憶體對齊
#include
struct s1
;struct s2
;int main()
分析4位元組對齊的情況:s2是
20,s1是
8 s1的記憶體分配:
s2的記憶體分配:
注意:結構體中的結構體,s1是一體的,short已經由於long進行了記憶體對齊,後面還空了兩個位元組的記憶體,其實此時的short已經變成了4個位元組了!!!即結構體不可拆,不管是多少位元組對齊,他們都是一體的。
分析8位元組對齊的情況:s2是24,s1是8
s18位元組對齊記憶體分配:
s2位元組對齊記憶體分配:
注意:乙個位元組對齊的原則:以什麼為對齊引數,首先我們要知道編譯器或者自己定義的是多少位元組對齊的,這個數為n。然後我們要看這個結構體中的各個資料型別,找到所佔位元組數最大的型別,為m。如果n大於m,就以m為對齊引數,比如說乙個4位元組對齊的結構體中都是short,那這個結構體以2為對齊引數,當然是2了,如果m大於n,就以n為對齊引數,比如說在4位元組對齊的情況下的double型別。
結構體內存對齊
結構體內存對齊 一 什麼是位元組對齊,為什麼要對齊?現代計算機中記憶體空間都是按照byte劃分的,從理論上講似乎對任何型別的變數的訪問可以從任何位址開始,但實際情況是在訪問特定型別變數的時候經常在特 定的記憶體位址訪問,這就需要各種型別資料按照一定的規則在空間上排列,而不是順序的乙個接乙個的排放,這...
結構體內存對齊
一 什麼是位元組對齊,為什麼要對齊?現代計算機中記憶體空間都是按照byte劃分的,從理論上講似乎對任何型別的變數的訪問可以從任何位址開始,但實際情況是在訪問特定型別變數的時候經常在特 定的記憶體位址訪問,這就需要各種型別資料按照一定的規則在空間上排列,而不是順序的乙個接乙個的排放,這就是對齊。對齊的...
結構體內存對齊
對齊規則 每個特定平台上的編譯器都有自己的預設 對齊係數 也叫對齊模數 程式設計師可以通過預編譯命令 pragma pack n n 1,2,4,8,16來改變這一係數,其中的n就是你要指定的 對齊係數 規則 1 資料成員對齊規則 結構 struct 的資料成員,第乙個資料成員放在offset為0的...