謝邀。
結構體在C語言程序開發中,是不可或缺的語法。不過,相信不少C語言初學者遇到過這樣的問題:為什么結構體的size有時不等于它的所有成員的size之和呢?
C語言結構體大小等于它的所有成員大小之和嗎?
舉例來說,假設有結構體,它的C語言代碼如下,請看:
我們繼續編寫C語言代碼,依次輸出成員s,i,c占用內存空間的大小,相關代碼很簡單,請看:
編譯并執行這段C語言代碼,得到如下輸出:
那么按理說,結構體x占用的內存空間應該等于2+4+1=7字節,但是似乎實際結果與我們的預期并不一致:
上面這行C語言代碼輸出的結果是12!這是怎么回事呢?
解析
程序輸出的結果與我們的預期不一致,原因在于“對齊機制”。如果將結構體x看作是一個容器,鑒于成員s,i,c的長度參差不齊,C語言編譯器不得不“填充”一些額外的空間,以滿足“對齊機制”。
數據結構是否對齊不僅影響C語言程序的性能,有時甚至還會帶來意想不到的錯誤,例如訪問未對齊的數據,可能會導致硬件方面的問題(SIGBUS,總線錯誤),導致性能下架,以及破壞一些操作的原子性等并發安全保障。
所以,C語言編譯器在處理結構體時,如果沒有特別的指定,一般都會填充一些字節,以確保不違背對齊機制。以上面的結構體x為例,初學者可能會認為它的成員在內存中的布局如下:
但是,如果編譯器按照下面布局,處理器訪問之將更加方便:
不過,這樣排列結構體x的成員,會空出一些空間,對于處理器來說,小心的跳過這些空間還是有些麻煩,于是大多數C語言編譯器都會像下面這樣填充空穴:
這樣一來,整個結構體x占用內存的空間,其實就是成員i占用空間的3倍了,也即12字節。
事實上,我們可以通過排列結構體x成員的順序,來優化其占用內存的大小,例如:
小結
本節主要討論了C語言中結構體大小并不一定等于它所有成員大小之和的原因,應該注意,結構對齊在C語言標準中是implementationdefined,不同的C語言編譯器可能選擇不同的數據對齊方式,從而導致不同和不兼容的數據布局。因此,在使用不同編譯器開發C語言程序時,了解編譯器是如何對齊數據是很重要的。
一些編譯器可以指定結構對齊的方式,例如#pragma語句。