1 什麼是偏移量
1.1 偏移量是結構體成員變數相對於結構體變數起始位址的相對偏移量。
1.2 第乙個結構體成員變數的偏移量為0。
1.3 從第二個結構體成員變數開始,其偏移量為該成員變數前乙個成員變數的偏 移量 加上該成員變數的大小。
2 結構體大小的理論計算值
在理論情況下(不進行記憶體對其的情況下),結構體的大小為最後乙個成員變數的偏移量大小加上該成員變數大小。
3 什麼是記憶體對齊
現代計算機中記憶體空間都是按照byte劃分的,從理論上講似乎對任何型別的變數的訪問可以從任何位址開始,但實際情況是在訪問特定型別變數的時候經常在特 定的記憶體位址訪問,這就需要各種型別資料按照一定的規則在空間上排列,而不是按照固定順序的乙個接乙個的排放,這就是對齊。
4 為什麼要記憶體對齊?
4.1 平台原因(移植原因)
不是所有的硬體平台都能訪問任意位址上的任意資料,某些硬體平台只能在某些位址處取 某些特定型別的資料,否則丟擲硬體異常。
4.2效能原因
經過記憶體對齊之後,cpu的記憶體訪問速度大大提公升。
cpu把記憶體當成是一塊一塊的,塊的大小可以是2,4,8,16 個位元組,因此cpu在讀取記憶體的時候是一塊一塊進行讀取的,塊的大小稱為(memory granularity)記憶體讀取粒度。
我們再來看看為什麼記憶體不對齊會影響讀取速度?
假設cpu要讀取乙個4位元組大小的資料到暫存器中(假設記憶體讀取粒度是4),分兩種情況討論:
1.資料從0位元組開始
2.資料從1位元組開始
解析:當資料從0位元組開始的時候,直接將0-3四個位元組完全讀取到暫存器,結算完成了。
當資料從1位元組開始的時候,問題很複雜,首先先將前4個位元組讀到暫存器,並再次讀取4-7位元組的資料進暫存器,接著把0位元組,4,6,7位元組的資料剔除,最後合併1,2,3,4位元組的資料進暫存器,對乙個記憶體未對齊的暫存器進行了這麼多額外操作,大大降低了cpu的效能。
5 誰來進行記憶體對齊
記憶體對齊由編譯器來完成,編譯器為程式中的每個資料單元安排在合適的位置上,從而導致了不同的宣告順序的結構體大小不同。
6 記憶體對齊的規則是什麼
第乙個成員在與結構體變數偏移量為0的位址處。
其他成員變數要對齊到某個數字(對齊數)的整數倍的位址處。對齊數=編譯器預設的乙個對齊數與該成員大小的較小值,在vs環境下預設值為8,在linux環境下預設值為4。
結構體的總大小為最大對齊數(每個成員變數都有乙個對齊數)的整數倍。
如果巢狀了結構體的情況,被巢狀的結構體對齊到其自身對齊數的整數倍處(結構體的對齊數就是其內部成員中最大的對齊數),此時結構體的整體大小就是所有最大對齊數(含被巢狀結構體的對齊數)的整數倍。
7 看乙個例子
struct student;
第乙個變數 a 的偏移量為1 佔乙個位元位--------對應規則1
第二個變數 b 要對齊到 它的對齊數(4)的位置,所以b的對齊首位址為4,佔4個位元位-----對應規則2
第三個變數 c的要對齊到它的對齊數(1)整數倍的位置,所以c的對齊首位址為9,佔乙個位元位 -----對應規則3
此時結構體的大小為 1(char)+偏移量3 +int 4 + char 1 =9;
此時需要滿足規則4 即結構體本身的對齊, 結構體大小應該是最大對齊數的整數倍 ,變數 a b c 的 對齊數依次 為1 4 1 ,最大對齊數為4 所以結構體大小為4 的倍數 為保證不浪費記憶體 所以結構體大小為 12 (4 的整數倍)
8 再看乙個例子
struct student;
結構體大小為 1(char)+1(char) + 2個偏移量 + 4(int) = 8
9最後乙個例子(結構體巢狀)
struct s1
; struct s2
;
結構體s2的大小為 1 (char) +7個偏移量 +8(s1) + d(double)=24
參考資料
參考資料
結構體大小計算
c語言 結構體大小計算 個人標籤啥東東封尾機 參考 一 結構體變數中成員的偏移量必須是成員大小的整數倍 0被認為是任何數的整數倍 eg typedef struct stu4 stu4 typedef struct stu5 stu4 這兩個結構體大小都為8 已驗證 二 結構體大小必須是所有成員大小...
結構體大小計算
結構體中的成員可以是不同的資料型別,成員按照定義時的順序依次儲存在連續的記憶體空間。和陣列不一樣的是,結構體的大小不是所有成員大小簡單的相加,需要考慮到系統在儲存結構體變數時的位址對齊問題。看下面這樣的乙個結構體 struct stu1 先介紹乙個相關的概念 偏移量。偏移量指的是結構體變數中成員的位...
結構體大小計算
結構體成員偏移量必須是成員大小的整數倍 結構體的大小必須是成員大小的整數倍 陣列,結構體除外 雖然浪費空間,但按照計算機的訪問規則,這種對齊方式,提高了效率 struct s1 int b 4float c 4double d 8 c pragma pack 4 指定向4對齊,而不是8 struct...