位元組對齊(c c ) (僅供學習參考)

2021-06-22 02:22:33 字數 4050 閱讀 4408

概述:

對於結構體:

位元組對齊準則:
(1),結構體變數的首位址能夠被其最寬基本型別成員大小所整除;
(2),結構體每個成員相對於結構體首位址的偏移量(offset)都是該成員大小的整數倍,如有需要,編譯器會在成員之間加上中間填充位元組;
(3),結構體總大小為結構體最寬基本型別成員大小的整數倍,如有需要,編譯器會在最末乙個成員之後加上末尾填充位元組。
第(2)、(3)條準則決定了結構體變數佔據記憶體空間的大小。

知識擴充套件1:若出現結構體巢狀,則準則(2)、(3)應改為:
(2),復合成員相對於結構體首位址的偏移量是復合成員中最寬基本型別成員大小的整數倍;
(3),結構體總大小為結構體最寬基本型別成員大小整數倍。

知識擴充套件2,若結構體內部出現陣列,則準則2應為:
(2),陣列相對於結構體首位址的offset是該陣列成員大小的整數倍。

對於共用體:
原則上,共用體大小取決於佔據最多記憶體的成員的長度。但位元組對齊準則(3)仍然成立。

詳情請參照以下分析:

對於結構體:

首先理解位元組對齊準則:
(1),結構體變數的首位址能夠被其最寬基本型別成員大小所整除。
(2),結構體每個成員相對於結構體首位址的偏移量(offset)都是該成員大小的整數倍,如有需要,編譯器會在成員之間加上中間填充位元組。
(3),結構體總大小為結構體最寬基本型別成員大小的整數倍,如有需要,編譯器會在最末乙個成員之後加上末尾填充位元組。
第(2)、(3)條準則決定了結構體變數佔據記憶體空間的大小。

基本型別指:char,short,int,float,double。
資料寬度即其sizeof的大小。

eg:

struct a;

structb;

則sizeof(a)=?,sizeof(b)=?

解:a中,char佔1位元組,short佔2,則short相對於結構體首位址的offset(偏移量)=1,為滿足準則(2),必須新增中間填充位元組1;

float佔4位元組,相對於結構體首位址offset=(1+1+2)(紅色為填充部分)即4,滿足準則(2);

此時結構體大小為(1+1+2+4)=8(紅色為填充部分),是最寬基本型別float整數倍,滿足準則(3)。

所以可得出:sizeof(a)=8。

對於b:b中,char佔1,float佔4,則float相對於結構體首位址的offset=1,為滿足準則(2),必須新增中間填充位元組3;

short佔2,相對於結構體首位址offset=(1+3+4)(紅色為填充部分)即8,是short所佔位元組的整數倍,滿足準則(2)。

此時結構體大小為(1+3+4+2)=10(紅色為填充部分),不是最寬基本型別float的整數倍,這時,末尾必須新增末尾填充位元組2,即(1+3+4+2 +2)=10(紅色為填充部分)。

所以最後總大小為12;

總結:分析時只要這樣即可:
對於a:1 

1  2 4 (紅色為填充部分)

對於b:1 

3  4 2 

2(紅色為填充部分)

這樣就可以直觀的得到結構體大小。
遷移eg:structc; 則sizeof(c)=?(答案:12)

知識擴充套件1:若出現結構體巢狀,則準則(2)、(3)應改為:

(2),復合成員相對於結構體首位址的偏移量是復合成員中

最寬基本型別成員大小的整數倍。

(3),結構體總大小為結構體

最寬基本型別成員大小整數倍。

eg:

struct

a;}b;

則sizeof(b)=?

解:先計算a大小:8  4  4  8    1    7(紅色為填充部分),得到為32;

所以對於b,排列:4     1    

3     8    32(紅色為填充部分);

此時成員d的offset=8,前面填充3位元組,滿足準則2;

a的offset=16,是a中最寬基本型別double所佔位元組數(8)的整數倍,滿足擴充套件準則2;

此時b大小為48,是b中最寬基本型別double的整數倍,滿足擴充套件準則3.

所以最後sizeof(b)=48;

知識擴充套件2,若結構體內部出現陣列,則準則2應為:
(2),陣列相對於結構體首位址的offset是該陣列成員大小的整數倍。

eg :struct c; 則sizeof(c)=?

解:double大小為8位元組,所以double[2]為16;而指標大小均為4,
所以c可排列為:
16 4 

4 (紅色為填充部分)

得到sizeof(c)=24;

eg:struct l;則sizeof(l)=?

解:char* c的大小為4,offset為0;double d[2]的大小為16,offset為double長度8的倍數,這裡即取8;結構體總大小也是double長度8的整數倍。
所以l可排列為:
4 

4 16 (紅色為填充部分)

得到sizeof(l) = 24;

對於共用體:

原則上,共用體大小取決於佔據最多記憶體的成員的長度。但位元組對齊準則(3)仍然成立。eg:

union

e;則sizeof(e)=8;

union u

;則sizeof(union u) = 24;

C C 位元組對齊

什麼是對齊,以及為什麼要對齊 現代計算機中記憶體空間都是按照byte劃分的,從理論上講似乎對任何型別的變數的訪問可以從任何位址開始,但實際情況是在訪問特定變數的時候經常在特定的記憶體位址訪問,這就需要各型別資料按照一定的規則在空間上排列,而不是順序的乙個接乙個的排放,這就是對齊。對齊的作用和原因 各...

c c 位元組對齊

什麼是對齊,以及為什麼要對齊 現代計算機中記憶體空間都是按照byte劃分的,從理論上講似乎對任何型別的變數的訪問可以從任何位址開始,但實際情況是在訪問特定變數的時候經常在特定的記憶體位址訪問,這就需要各型別資料按照一定的規則在空間上排列,而不是順序的乙個接乙個的排放,這就是對齊。對齊的作用和原因 各...

C C 位元組對齊

概念 對齊跟資料在記憶體中的位置有關。如果乙個變數的記憶體位址正好位於它長度的整數倍,他就被稱做自然對齊。比如在32位cpu下,假設乙個整型變數的位址為0x00000004,那它就是自然對齊的。為什麼位元組需要對齊 根本原因在於cpu訪問資料的效率問題。假設上面整型變數的位址不是自然對齊,比如為0x...