【C语言进阶深度学习记录】二十 结构体大小计算与结构体内存布局的详细方法
- 結構體大小的計算往往是面試筆試常考的知識。對于簡單的結構體,可以一眼看出來,對于復雜的結構體,該如何計算結構體占用內存的大小呢?
- 本文學習所使用的編譯器是gcc 4.4.5 使用其他編譯器或者使用Windows 上的編譯器有可能不太一樣。
文章目錄
- 1 什么是內存對齊?
- 2 struct占用的內存大小如何計算
- 2.1 struct結構體大小計算案例分析-結構體中沒有結構體
- 2.2 struct結構體大小計算案例分析-結構體中有一個結構體成員
- 3 總結
1 什么是內存對齊?
先來加單的說一下為什么需要內存對齊:
什么是內存對齊?
- 不同類型的數據在內存中按照一定的規則排列
- 但是不一定是順序的一個接一個的排列
例如下圖中的兩個結構體的大小是不一樣的,因為它們的內存布局是不一樣的:
它們的內存布局如下圖:
拓展: #pragma pack 用于指定內存的對齊方式。用于修改編譯器的默認對齊方式
一般來講,在Linux系統中,編譯器的默認對我方式是4字節對齊。下圖中的代碼,可以將對齊方式修改為1字節對齊:
2 struct占用的內存大小如何計算
對于不同的內存對齊方式,上面的結構體在內存中的布局是不一樣的,那么我們如何來計算不同的對齊方式在內存中的布局是什么樣的呢?
需要根據以下三點:
第一個struct成員永遠起始于 0偏移處
每個成員按其類型大小和pack參數中較小的一個 進行對齊
2.1 偏移地址必須能被對齊參數整除
2.2 如果一個結構體中有一個變量也是結構體,那么這個內部的結構體成員的對齊大小就按照其內部最大的數據成員作為其大小來計算。(這里有點繞,看最后的一個例子就會明白)
結構體總長度,必須為所有對齊參數的整數倍
- 只需要按照上述三點計算方法,就可以計算出所有結構體的大小以及內存布局的樣式
2.1 struct結構體大小計算案例分析-結構體中沒有結構體
如下面的代碼:
- 24-3.c
- 編譯運行結果為:
sizeof(Test1) = 10
sizeof(Test2) = 8
- 結果分析1–Test1:
對于結構體Test1,2字節對齊,按照上述三個計算條件有:
struct Test1 { //對齊方式 大小 起始地址 占用的內存地址位置 char c1; 2 大于 1 0 0 short s; 2 等于 2 2(被對齊參數2整除) 2~3 char c2; 2 大于 1(對齊參數) 4 4 int i; 2(對齊參數) 小于 4 6(被對齊參數2整除) 6~9 };然后根據:
每個成員按其類型大小和pack參數中較小的一個 進行對齊。比如上面的起始地址計算那里,都是被對齊參數2整除,這個2是類型大小和pack參數中較小的一個
2.1 偏移地址必須能被對齊參數整除
這一條規則計算每個成員的起始地址。如上面的計算。
- 結果分析2–Test2
對于結構體Test2,4字節對齊,按照上述三個計算條件有:
struct Test2 { //對齊方式 大小 起始地址 占用的內存地址位置 char c1; 4 大于 1(對齊參數) 0 0 char c2; 4 大于 1(對齊參數) 1(被對齊參數1整除) 1 short s; 4 大于 2(對齊參數) 2(被對齊參數2整除) 2~3 int i; 4 等于 4(對齊參數) 4(被對齊參數4整除) 5~7 };然后再根據:
每個成員按其類型大小和pack參數中較小的一個 進行對齊。比如上面的起始地址計算那里,對齊參數分別為1,1,2,4
2.1 偏移地址必須能被對齊參數整除
這一條規則計算每個成員的起始地址。如上面的計算。
經過上面的兩個結構體大小的計算,可以很容易的畫出其內存圖
2.2 struct結構體大小計算案例分析-結構體中有一個結構體成員
再看一個復雜的結構體大小的計算
- 代碼 24-4.c
運行結果為:
sizeof(struct S1) = 8
sizeof(struct S2) = 20
S1很好分析。下面我們分析S2
struct S2 //對齊方式 大小 起始地址 占用的內存地址位置 {char c; 4 大于 1(對齊參數) 0 0 struct S1 d; 4 等于 4(這個是S1中最大參數大小) 4(被4整除) 4~11(S1實際大小為8) double e; 4(對齊)小于 8 12(被4整除) 12~19 };注意: 上面S2中的S1實際大小是8,那個4是作為與對齊方式比較時(選取較小的作為對齊參數)選取S1中最大的數據成員大小。
然后再根據:
每個成員按其類型大小和pack參數中較小的一個 進行對齊。比如上面的起始地址計算那里,對齊參數分別為0,4,12
2.1 偏移地址必須能被對齊參數整除
2.2 如果一個結構體中有一個變量也是結構體,那么這個內部的結構體成員的對齊大小就按照其內部最大的數據成員作為其大小來計算
這一條規則計算每個成員的起始地址。如上面的計算。
我所使用的編譯器gcc 4.4.5 不支持8字節對齊方式
3 總結
注意好好理解上述計算結構體大小的計算方法。然后自己畫畫內存圖。
總結
以上是生活随笔為你收集整理的【C语言进阶深度学习记录】二十 结构体大小计算与结构体内存布局的详细方法的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 思科命令敲错等待解决方案
- 下一篇: 【软件开发底层知识修炼】十三 链接器-如