4.補充
5.總結
宣告乙個結構體型別,它所佔位元組為所有成員的位元組的總和?
顯然是錯誤的
基本的資料型別有char int double float。
這個條件是很重要的,當你把結構體所佔記憶體位元組數算出來以後,你不要立即下結論,這個時候你要看看此時的值是否為最寬基本資料型別大小的整數倍。而往往有人會忽略這一點。
結構體中元素是按照定義順序乙個乙個放到記憶體中去的,但並不是緊密排列的。從結構體儲存的首位址開始,每乙個元素放置到記憶體中時,它都會認為記憶體是以它自己的大小來劃分的,因此元素放置的位置一定會在自己寬度的整數倍上開始。
結構體成員的位址-結構體首位址=偏移量 ,必須是當前成員的整數倍。
首先系統會將字元型變數a存入第0個位元組(相對位址,指記憶體開闢的首位址);然後在存放整形變數b時,會以4個位元組為單位進行儲存,由於第乙個四位元組模組已有資料,因此它會存入第二個四位元組模組,也就是存入到4~8位元組;同理,存放雙精度實型變數c時,由於其寬度為8,其存放時會以8個位元組為單位儲存,也就是會找到第乙個空的且是8的整數倍的位置開始儲存,此例中,此例中,由於頭乙個8位元組模組已被占用,所以將c存入第二個8位元組模組。整體儲存示意圖如圖1所示。
我們現在來看下實驗結果。
現在我給大家出個題目,自己去算算此時結構體所佔記憶體的大小是多少?
這個題和上面那個題就是b,c的位置換了一下,但是最終的結果卻不一樣。
算出來了嗎?
答案是24.
解釋如下:
我的經驗告訴我,在求結構體記憶體大小的時候,一定要畫圖,這是最直觀且簡單的一種方式。
接下來再做幾道題,多練練,就可以掌握了。
圖如下:
前面所介紹的都是元素為基本資料型別的結構體,那麼含有指標、陣列或是其它結構體變數或聯合體變數時該如何呢?
1.包含指標型別的情況。只要記住指標本身所佔的儲存空間是4個位元組就行了,而不必看它是指向什麼型別的指標。
2.含有構造資料型別(陣列、結構體和聯合體)的情況。
首先要明確的是計算儲存空間時要把構造體看作乙個整體來為其開闢儲存空間。
其次要明確的是在最後補齊時是按照所有元素中的基本資料型別元素的最長寬度來補齊的,也就是說雖然要把構造體看作整體,但在補齊的時候並不會按照所含結構體所佔儲存空間的長度來補齊的(即使它可能是最長的)。
經測試,可知sizeof(x)為16,sizeof(y)為24。即計算y的儲存長度時,在存放第二個元素b時的初始位置是在double型的長度8的整數倍處,而非16的整數倍處,即系統為b所分配的儲存空間是第8~23個位元組。
如果將y的兩個元素char型的a和x型的b調換定義順序,則系統為b分配的儲存位置是第0~15個位元組,為a分配的是第16個位元組,加起來一共17個位元組,因為最長基本型別double,所以結構體內存所佔位元組為8的整數倍,因此要補齊到8的整數倍,即24。測試後可得sizeof(y)的值為24。
1.由於結構體所佔空間與其內部元素的型別有關,而且與不同型別元素的排列有關,因此在定義結構體時,在元素型別及數量確定之後,我們還應該注意一下其內部元素的定義順序。以至於可以可以減少記憶體。
2.記憶體對齊的目的是為了更好地操作結構體中的成員,所以宣告結構體變數的時候,我們要注意結構體所佔的記憶體數。
3.只有乙個結構體成員不存在記憶體對齊。
總的來說,對於結構體內存對齊規則並不是很難,但是也是很重要的,如果你以後是要做系統架構師的話,那你還是得要了解這方面的知識。
如果你覺得還不錯的話,給個三連!
結構體內存對齊規則
今天又聽了一遍結構體內存對齊規則,明白了 按照結構體內存規則來計算,再遇到結構體套結構體或結構體套陣列的情況,也能計算清楚。include stdafx.h include include include include struct tagtest 結構成員的對齊開始位址由結構成員size和預設對...
結構體內存對齊規則
記憶體對齊是出於提高記憶體訪問效率的考慮,其記憶體對齊規則如下 1 結構體中第乙個成員的位址偏移 offset 為0 2 其餘成員按照定義順序,其位址偏移量為各自對齊數的整數倍 3 最終結構體的整體大小為其最大對齊數的整數倍,不足在末尾補齊。4 對於內部巢狀了結構體的情況,其對齊數為該內嵌結構體的最...
C 中結構體內存對齊規則
c語言中結構體內存對齊規則 對齊規則 記憶體偏移為該資料型別的最小整數倍 總體占用記憶體為結構體中最大資料型別的整數倍 舉個?首先,要搞清楚每一種資料型別占用記憶體為多少,在這裡,是針對64位linux macos 為例的 nslog char zd sizeof char nslog double...