1:某個成員距離首位置的偏移量最小是該成員大小的一倍。為什麼要記憶體對齊?點這裡2:所有成員的大小之和應該是最大成員大小的整數倍。
來段**解釋下:
我們接下來就來解釋為什麼stu1和stu2分別是8和12,主要還是我們的兩個規則:
注意:下面的表示方法,例如short b 就會在兩個位元組中填b,表示占用兩個位元組*
對於stu1來說,a是char型別的,佔1個位元組.如圖:
b是short型別的,佔2個位元組,由於規則1,某個成員距離首位置的偏移量最小是該成員的1倍,但是此時b距離首位置只有a這乙個位元組,所以補乙個位元組,如圖:
再說到c為乙個int型別的,占用4個位元組,我們用規則1去驗證,現在它距離首位置的偏移量是4,並且它自己也占用4個位元組,剛好是一倍,滿足規則1,再來看規則2,所有成員的大小之和應該是最大成員大小的整數倍,現在c為int型別,加上前面的4個位元組,一共是8個位元組,是最大成員c的位元組數的2倍,滿足規則2,所以就直接將c放在後面.如圖:
那麼對於stu2來說呢,
首先char a還是一樣的,a占用乙個位元組.如圖:
再說b,b是乙個int型別的變數,首先根據我們的規則1,距離首位置的偏移量至少是該成員的一倍,所以應該補3個位置,如圖:
再說short c,根據規則1,現在的成員偏移量為8,c的大小為2,滿足規則1,再來看規則2,目前我們所有成員的大小為10,並不滿足目前成員大小為最大成員(int b)大小的整數倍,所以需要再補兩個位元組,總大小構成12,就是4的整數倍了,如圖:
好,基本上就是這樣,但是有沒有思考過我在最後補的兩個位元組為什麼要補在最後呢,難道不會是下面這樣嗎?
好,帶著這個問題,我們來看看下面的這段**:
恩,這個執行結果有點糟糕啊,第乙個執行結果到是沒什麼問題,但是第二個394499怎麼解釋呢.
原因就要牽扯到記憶體對齊的問題,再次回憶下記憶體對其兩個原則,乙個最小,乙個最大,乙個最小:某個成員目前的偏移量最小是這個成員的一倍,乙個最大:所有成員的大小之和是最大成員的整數倍.
現在再來分析:我分別給a,b,c賦值3,5,6.即分別占用1,1,2個位元組,總共就是4個位元組,即乙個int,那麼我最後printf中的值肯定就是這4個位元組組成的,按照低位址存入,高位址輸出的原則,所以在記憶體中會是這樣計算,6*2^16+5*2^8+3*2^0 = 394499,(2^16是巨集觀把握的結果)如圖:
所以補的位置就是上面例子的位置,而不是先補後加資料,原因上面的例子已經得到很好的驗證,至於為什麼要這樣,不是補在低位呢,我還沒研究這麼深,搞懂再說吧……
有關記憶體分布
linux下程序的記憶體分布 核心空間 棧 棧的下面有預留空間,棧記憶體方向向低位址延伸 動態鏈結對映區 堆 堆的上方有預留空間,堆記憶體方向向高位址延伸 讀寫部分 唯讀部分 預留空間 棧 例項 棧頂 0xbfffffff 0xbffffffb 0xbffffff8 0xbffffff4 esp暫存...
C C 中有關記憶體問題的彙總
型別 32位環境下所佔位元組數 64位環境下所佔位元組數 char11 short int22 int4 4long int48 long long int88 float44 double88 char 44 int 44 特別地,null占用4位元組。其在記憶體中分配的位置圖如下。1 堆 hea...
個人有關記憶體的思考
對於應用程式而言,記憶體中儲存區域大致有堆 棧 靜態區域三個部分。系統在分配記憶體的時候,會在記憶體中尋找乙個能夠滿足申請大小的區域進行標記,並返回此區域的大小。在應用程式執行時,系統為應用程式分配的只是虛擬的位址空間,並不是實際的物理儲存器。這就需要給程序預定的區域 位址空間 調撥物理儲存器 記憶...