結構體共用體占用空間大小區別 記憶體對齊計算

2021-10-02 04:27:41 字數 2401 閱讀 9486

(題目來自牛客網)

在32位機器上

設有以下說明和定義:

typedef union date;

struct data too;

date max;

則語句 printf("%d",sizeof(struct data)+sizeof(max));的執行結果是:

52共享體

union 維護足夠的空間來置放多個資料成員中的「一種」,而不是為每乙個資料成員配置空間,在union 中所有的資料成員共用乙個空間,同一時間只能儲存其中乙個資料成員,所有的資料成員具有相同的起始位址。例子如下: 

union statemachine 

;乙個union 只配置乙個足夠大的空間以來容納最大長度的資料成員,以上例而言,最大長度是double 型態,所以statemachine 的空間大小就是double 資料型別的大小。

結構體【記憶體對齊】

**自結構體變數的所有成員占用不同的儲存空間,結構體中的成員可以是不同的資料型別,成員按照定義時的順序依次儲存在連續的記憶體空間。和陣列不一樣的是,結構體的大小不是所有成員大小簡單的相加,需要考慮到系統在儲存結構體變數時的位址對齊問題。

看下面這樣的乙個結構體:

[cpp] view plain copy print?

struct stu1  

;  用sizeof求該結構體的大小,發現值為12。int佔4個位元組,char佔1個位元組,結果應該是9個位元組才對啊,為什麼呢?

先介紹乙個相關的概念——偏移量。偏移量指的是結構體變數中成員的位址和結構體變數位址的差。結構體大小等於最後乙個成員的偏移量加上最後乙個成員的大小。顯然,結構體變數中第乙個成員的位址就是結構體變數的首位址。因此,第乙個成員i的偏移量為0。第二個成員c的偏移量是第乙個成員的偏移量加上第乙個成員的大小(0+4),其值為4;第三個成員j的偏移量是第二個成員的偏移量加上第二個成員的大小(4+1),其值為5。

(1)結構體變數中成員的偏移量必須是成員大小的整數倍(0被認為是任何數的整數倍) 

(2)結構體大小必須是所有成員大小的整數倍,也即所有成員大小的公倍數。

上面的例子中前兩個成員的偏移量都滿足要求,但第三個成員的偏移量為5,並不是自身(int)大小的整數倍。編譯器在處理時會在第二個成員後面補上3個空位元組,使得第三個成員的偏移量變成8。結構體大小等於最後乙個成員的偏移量加上其大小,上面的例子中計算出來的大小為12,滿足要求。

再來看另外乙個例子:

[cpp] view plain copy print?

struct stu2  

;  成員k的偏移量為0;成員t的偏移量為4,都不需要調整。但計算出來的大小為6,顯然不是成員k大小的整數倍。因此,編譯器會在成員t後面補上2個位元組,使得結構體的大小變成8從而滿足第二個要求。 

由此可見,結構體型別需要考慮到位元組對齊的情況,不同的順序會影響結構體的大小。

對比下面兩種定義順序:

[cpp] view plain copy print?

struct stu3  

struct stu4  

雖然結構體stu3和stu4中成員都一樣,但sizeof(struct stu3)的值為12而sizeof(struct stu4)的值為8。

對於巢狀的結構體,需要將其展開。對結構體求sizeof時,上述兩種原則變為:

(1)展開後的結構體的第乙個成員的偏移量應當是被展開的結構體中最大的成員的整數倍。

(2)結構體大小必須是所有成員大小的整數倍,這裡所有成員計算的是展開後的成員,而不是將巢狀的結構體當做乙個整體。

看下面的例子:

[cpp] view plain copy print?

struct stu5  

ss;   

int k;  

}  結構體stu5的成員ss.c的偏移量應該是4,而不是2。整個結構體大小應該是16。

下述**測試原則2:

[cpp] view plain copy print?

struct stu5  

ss;   

char a;  

char b;  

char d;  

char e;  

char f;  

}  結構體ss單獨計算占用空間為8,而stu5的sizeof則是20,不是8的整數倍,這說明在計算sizeof(stu5)時,將巢狀的結構體ss展開了,這樣stu5中最大的成員為ss.j,占用4個位元組,20為4的整數倍。如果將ss當做乙個整體,結果應該是24了。

另乙個特殊的例子是結構體中包含陣列,其sizeof應當和處理巢狀結構體一樣,將其展開,如下例子:

[cpp] view plain copy print?

struct ss  

;  cout《如何給結構體變數分配空間由編譯器決定,以上情況針對的是linux下的gcc。在windows下的vc平台也是這樣,至於其他平台,可能會有不同的處理。

結構體共用體占用空間區別 記憶體對齊

題目來自牛客網 在32位機器上 設有以下說明和定義 typedef union date struct data too date max 則語句 printf d sizeof struct data sizeof max 的執行結果是 52union 維護足夠的空間來置放多個資料成員中的 一種 ...

結構體占用空間的大小 pragma pack

pragma pack 8 struct s1 struct s2 pragma pack sizeof s2 結果為24.成員對齊有乙個重要的條件,即每個成員分別對齊.即每個成員按自己的方式對齊.也就是說上面雖然指定了按8位元組對齊,但並不是所有的成員都是以8位元組對齊.其對齊的規則是,每個成員按...

如何計算結構體及共用體大小

如何計算結構體及共用體大小 宣告 以下均為我乙個字乙個字打上去的,於大一上學期所作筆記 對於結構體 首先理解位元組對齊機制 1 結構體變數的首位址能夠被其最寬基本型別成員大小所整除。2 結構體每個成員相對於結構體首位址的偏移量 offset 都是該成員大小的整數倍,如有需要,編譯器會在成員之間加上中...