計算 sizeof(struct),很多初學者都會在這裡栽跟頭!
c語言中的結構體為我們提供了集中資料的機制,使用結構體可以將相關的資料存放在一起,組成乙個有機整體,方便使用。下面是乙個結構體示例:
struct tagphone
phone;
結構體看似簡單,但也要注意的地方,否則你很可能它會在未來某個時候讓你發狂! believe me~
就拿上面的結構體 phone 來說,它在記憶體中占用多少位元組?
當然是 7個位元組啦,怎麼算的呢? sizeof(char) + sizeof(int) + sizeof(short) = 1 + 4 + 2 = 7 ,恩,算術過程很正確。恭喜你,答錯了!!!
正確的計算方法
不是你的算術過程錯了,而是編譯器不是這樣計算的。
計算結構體大小時需要考慮其記憶體布局,結構體在記憶體中存放是按單元存放的,每個單元多大取決於結構體中最大基本型別的大小。
如,char 是 1 位元組,short 是 2 位元組, int 是 4 位元組(之前這裡筆誤了,謝謝網友提醒~), long 是 4 位元組 , long long 是 8 位元組(具體情況視編譯器而定,不過一般是這樣)
比如上面的結構體 phone 其儲存單元就是 4 位元組(因為最大的型別為int),其儲存過程是這樣的:
圖 1 結構體 phone 的記憶體布局
先儲存 char 型別的字段a,佔 1 個位元組;
再儲存 int 型別的字段b,佔 4 個位元組,但是儲存單元中只剩下3個位元組空間,而編譯器是不會將乙個型別分割了儲存的,所以咋還是另起一行吧,所以 int 型別就儲存在乙個新的單元裡。
最後儲存 short 型別的字段c,佔 2 個位元組。
圖 1 中的空白空間雖然沒有使用,但是它也會算作結構體的一部分,所以最終結構體 phone 占用的儲存空間是 4 * 3 = 12 位元組。
做的更好些! 占用更少的儲存空間
上面圖 1 中顯示的結構體 phone 的記憶體布局中,有好多空白空間沒有使用導致浪費。其實我們可以做的更好些,只需要編碼時稍稍改變下結構體中字段的順序其產生的結構會令你的程式節省不少空間。
將上面結構體 phone 中欄位 b 和字段 c 交換下位置,得到新的結構體 phone2:
圖 2 結構體 phone2 的記憶體布局
上面這個結構體計算儲存空間,sizeof(phone2) = 4 * 2 = 8 位元組,比上面phone節省了 1/3 的儲存空間。
做到最好! 占用最少的儲存空間
上面的雖然情況有所好轉,節省了不少空間,但是還是有空白空間被浪費,而且還需要我們編碼時考慮結構體字段的順序。除此之外,還有很重要的乙個因素,就是我們用 sizeof 求出的結構體大小與結構體中每個欄位所佔空間之和不等,雖然這一點我們現在已經清楚怎麼回事,但是我們還是希望無論結構體中字段順序如何,sizeof 求出的大小總是和結構體中所有欄位所佔空間之和相等。 怎麼解決呢?
辦法相當簡單,相比你猜到了~~, 記憶體中資料的最小單元既然是位元組,那幹嘛不以位元組為單位呢?所以結構體 phone 變為如下形式:
圖 2 結構體 phone2 的記憶體布局
上面結構計算大小,sizeof(phone3) = 1 + 2 + 4 = 7, 其大小為結構體中個字段大小之和,這也是最節省空間的一種寫法。
總結
上面提到的三種寫法,各有各的優點:
第一種寫法,空間浪費嚴重,sizeof 計算大小與預期不一致,但是保持了每個欄位的資料型別。這也是最常見的漫不經心的寫法,一般人很容易這樣寫;
第三種寫法,最節省空間的寫法,也是使用 sizeof 求大小與預期一樣的寫法,但是全部使用位元組型別,丟失了字段本生的資料型別,不方便使用;
第二種寫法,介於第一種和第三種寫法之間,其空間上比較緊湊,同時又保持了結構體中字段的資料型別。
只要了解是這些寫法的差異性,可以視情況選用。
C語言中的結構體大小
現代計算機中,記憶體空間按照位元組劃分,理論上可以從任何起始位址訪問任意型別的變數。但實際中在訪問特定型別變數時經常在特定的記憶體位址訪問,這就需要各種型別資料按照一定的規則在空間上排列,而不是順序乙個接乙個地存放,這就是對齊。不同硬體平台對儲存空間的處理上存在很大的不同。某些平台對特定型別的資料只...
C語言中結構體大小的計算(記憶體對齊詳解)
首先來看乙個例子 struct s 我們先來計算一下這個結構體的大小,如果不存在記憶體對齊這個問題,按理說這個結構體應該佔 1 4 1 6個位元組 然而事實上它佔了12個位元組,為什麼?我們需要解決下面幾個問題。看上面的圖 利用這四個規則就可以計算結構體的大小。這時參照上面的圖中第二種情況來計算,對...
C語言 計算結構體大小
結構體中的成員可以是不同的資料型別,成員按照定義時間的順序依次儲存在連續的記憶體空間。和陣列不一樣的是,結構體的大小不是所有成員大小簡單的相加,需要考慮到系統在儲存結構體變數時的位址對其問題。結構體對齊規則 通入下面例題,計算結構體大小 題1 struct s1 題2 struct s2 題3 st...