回覆列表
  • 1 # IT劉小虎

    結構體在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語言標準中是 implementation defined,不同的C語言編譯器可能選擇不同的資料對齊方式,從而導致不同和不相容的資料佈局。因此,在使用不同編譯器開發C語言程式時,瞭解編譯器是如何對齊資料是很重要的。

    一些編譯器可以指定結構對齊的方式,例如 #pragma 語句。

  • 中秋節和大豐收的關聯?
  • 高中物理,共振的振幅怎麼比較,跟質量或者擺線長有關嗎?