在日常的開發工作中,時常要用到結構體的定義工作,但是結構體中資料的定義順序是否合理直接影響了結構體所佔記憶體的大小,所以了解c語言中記憶體對齊的知識十分有必要。
關於記憶體對齊的原則,我們首先討論沒有定義巨集 #pragam pack 的情況,在該巨集沒有定義的情況之下,c語言中結構體的記憶體對齊問題主要滿足一下三條原則:
1.資料成員對齊規則:struct, union的資料成員,第乙個資料成員放在offset為0的地方,之後的資料成員的儲存起始位置都是放在該資料成員大小的整數倍位置。如在32bit的機器上,int的大小為4,因此int儲存的位置都是4的整數倍的位置開始儲存。
2.結構體作為資料成員的對齊規則:在乙個struct中包含另乙個struct,內部struct應該以它的最大資料成員大小的整數倍開始儲存。如 struct a 中包含 struct b, struct b 中包含資料成員 char, int, double,則 struct b 應該以sizeof(double)=8的整數倍為起始位址。
3.收尾工作的對齊規則:整個struct的大小,應該為最大資料成員大小的整數倍。
例項展示:
struct a
; // 記憶體大小:sizeof(a) = (1+7) + 8 + (4+4) = 24, 補齊[20]...[23] ---- 規則3
struct b
; // 記憶體大小:sizeof(b) = (4+4) + 24 + (1+7) = 40, 補齊[33]...[39]
*注釋:(1+7)表示該資料成員大小為1,補齊7位;(4+4)同理。
下面來解釋上面提到的巨集 #pragam pack的含義:
如果在**前新增 #pragam pack(1),則 sizeof(a) = 1 + 8 + 4 = 13; sizeof(b) = 4 + 13 + 1 = 18;
那麼可以猜到這個巨集的含義了麼?
它的意義就是,讓編譯器在編譯的時候,給結構體按照括號中的數字,比如為i,那麼就是i個位元組大小來進行對齊,也就是所有的變數按照 i 的倍數的大小的起始偏移開始儲存。
c語言中記憶體對齊問題
一 記憶體對齊的原因 大部分的參考資料都是如是說的 1 平台原因 移植原因 不是所有的硬體平台都能訪問任意位址上的任意資料的 某些硬體平台只能在某些位址處取某些特定型別的資料,否則丟擲硬體異常。2 效能原因 資料結構 尤其是棧 應該盡可能地在自然邊界上對齊。原因在於,為了訪問未對齊的記憶體,處理器需...
C語言中記憶體對齊詳解
首先由乙個程式引入話題 1 環境 vc6 windows sp22 程式13 include iostream 45 using namespace std 67 struct st1 8 1314 struct st215 20 21int main 2227 程式的輸出結果為 sizeof st...
C語言中的記憶體對齊
這階段一直想寫一篇部落格,其實有好多東西,先寫一下c語言中的記憶體對齊吧。大家都知道,在c語言中定義乙個變數,char是占用乙個位元組的,int占用四個位元組,float占用四個位元組,double占用八個位元組,short占用兩個位元組,long int占用四個位元組,long long神馬的是6...