乙個結構體變數定義完之後,其在記憶體中的儲存並不等於其所包含元素的寬度之和。
例一:#include
using namespace std;
struct x
s1;voidmain()
比如例一中的結構體變數s1定義之後,經測試,會發現sizeof(s1)= 16,其值不等於sizeof(s1.a) = 1、sizeof(s1.b) = 4和 sizeof(s1.c) = 8三者之和,這裡面就存在儲存對齊問題。
原則一:結構體中元素是按照定義順序乙個乙個放到記憶體中去的,但並不是緊密排列的。從結構體儲存的首位址開始,每乙個元素放置到記憶體中時,它都會認為記憶體是以它自己的大小來劃分的,因此元素放置的位置一定會在自己寬度的整數倍上開始(以結構體變數首位址為
0計算)。
比如此例,首先系統會將字元型變數a存入第0個位元組(相對位址,指記憶體開闢的首位址);然後在存放整形變數b時,會以4個位元組為單位進行儲存,由於第乙個四位元組模組已有資料,因此它會存入第二個四位元組模組,也就是存入到4~8位元組;同理,存放雙精度實型變數c時,由於其寬度為8,其存放時會以8個位元組為單位儲存,也就是會找到第乙個空的且是8的整數倍的位置開始儲存,此例中,此例中,由於頭乙個8位元組模組已被占用,所以將c存入第二個8位元組模組。整體儲存示意圖如圖1所示。
考慮另外乙個例項。
例二:struct x
s2;在例二中僅僅是將double型的變數和int型的變數互換了位置。測試程式不變,測試結果卻截然不同,sizeof(s2)=24,不同於我們按照原則一計算出的8+8+4=20,這就引出了我們的第二原則。
原則二:在經過第一原則分析後,檢查計算出的儲存單元是否為所有元素中最寬的元素的長度的整數倍,是,則結束;若不是,則補齊為它的整數倍。
例二中,我們分析完後的儲存長度為20位元組,不是最寬元素長度8的整數倍,因此將它補齊到8的整數倍,也就是24。這樣就沒問題了。其儲存示意圖如圖2所示。
掌握了這兩個原則,就能夠分析所有資料儲存對齊問題了。再來看幾個例子,應用以上兩個原則來判斷。
例三:struct x
s3;首先根據原則一來分析。按照定義的順序,先儲存double型的a,儲存在第0~7個位元組;其次是char型的b,儲存在第8個位元組;接下來是int型的c,順序檢查後發現前面三個四位元組模組都被占用,因此儲存在第4個四位元組模組,也就是第12~15位元組。按照第一原則分析得到16個位元組,16正好是最寬元素a的寬度8的整數倍,因此結構體變數s3所佔儲存空間就是16個位元組。儲存結構如圖3所示。
例四:struct x
s4;仍然首先按照第一原則分析,得到的位元組數為8+4+4+1=17;再按照第二原則補齊,則結構體變數s4所佔儲存空間為24。儲存結構如圖4所示:
例五:struct x
s5;同樣結合原則一和原則二分析,可知在s4的基礎上在結構體內部變數定義最後加入乙個int型變數後,結構體所佔空間並未增加,仍為24。儲存結構示意圖如圖5所示。
例六:如果將例五中加入的變數e放到第乙個定義的位置,則情況就不同了。結構體所佔儲存空間會變為32。其儲存結構示意圖如圖6所示。
struct x
s6;補充:前面所介紹的都是元素為基本資料型別的結構體,那麼含有指標、陣列或是其它結構體變數或聯合體變數時該如何呢? 1.
包含指標型別的情況。只要記住指標本身所佔的儲存空間是
4個位元組就行了,而不必看它是指向什麼型別的指標。
例七:structx structy struct z
; }; };
經測試,可知sizeof(x)、sizeof(y)和sizeof(z)的值都為4。
2.含有構造資料型別(陣列、結構體和聯合體)的情況。首先要明確的是計算儲存空間時要把構造體看作乙個整體來為其開闢儲存空間;其次要明確的是在最後補齊時是按照所有元素中的基本資料型別元素的最長寬度來補齊的,也就是說雖然要把構造體看作整體,但在補齊的時候並不會按照所含結構體所佔儲存空間的長度來補齊的(即使它可能是最長的)。
例八:struct x
;struct y
;經測試,可知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。
由於結構體所佔空間與其內部元素的型別有關,而且與不同型別元素的排列有關,因此在定義結構體時,在元素型別及數量確定之後,我們還應該注意一下其內部元素的定義順序。
結構體在記憶體中的對其原則
乙個結構體定義完了之後,其在記憶體中的儲存並不等於所有元素寬度之和。基本資料型別結構體遵循 原則一 結構體中的元素是按照定義的順序乙個個放到記憶體中去的,並不緊密排布。從記憶體儲存單元的首位址 0 開始,每乙個元素都認為記憶體根據它的大小來劃分,所以每乙個元素存放的位置從自己寬度的整數倍開始。原則二...
結構體在記憶體中的對齊規則
結構體在記憶體中的對齊規則 標籤 儲存 struct 測試iostream c2011 11 15 19 32 4717人閱讀 9 收藏 舉報乙個結構體變數定義完之後,其在記憶體中的儲存並不等於其所包含元素的寬度之和。例一 include using namespace std struct x c...
結構體在記憶體中對齊
剛剛完成乙個檔案的遷移程式,其中遇到了結構體對齊的問題,所以拿出來說說,與各位博友們分享。我的程式很簡單,就是把之前通過乙個結構體 fwrite 到檔案 a 裡的內容讀出,然後轉給另乙個結構體儲存。程式是簡單,但我擔心的是之前把結構體 fwrite 到檔案 a 的程式對齊結構體規則是怎樣的?一定要知...