關於結構體、聯合體、類的大小比較

在學習C語言的過程中,我們經常會遇到求結構體、聯合體或者類的大小。除了明確基本元素的大小,還需要考慮內存對齊帶來的影響。爲了提高計算機的讀寫速度,採用內存對齊的方式以空間換時間,因此要考慮到在不同的編譯環境下,內存字節對齊存在差異。

注:在此篇文章中的基本數據類型均爲在32位系統下。

結構體(struct):由一系列具有相同類型或不同類型的數據構成的數據集合。

在實際項目中,結構體和其他類型基礎數據類型一樣,結構體是大量存在的。結構體的大小不是結構體元素單純相加就行的,需要考慮到系統在存儲結構體變量時的地址對齊問題。對齊方式如下:

1.每個成員的偏移量都必須是當前成員所佔內存大小的整數倍,否則在成員之前加上偏移量;

2.當前所以成員大小計算完畢,編譯器判斷當前結構提的大小是否爲結構體中最大基本數據項的整數倍,如不是在最後一個成員後做字節填充。

	struct stuA//5
	{
		char name[4];//4
		char sex;//1
	};
	struct stuB//8
	{
		int num;//4
		char sex;//1
	};

stuA 中 name 爲4個字節,偏移量爲0,sex 爲1個字節,偏移量爲0,所有數據項計算結束,當前結構體大小爲5,不填充,stuA爲5個字節。

stuB 中 num 爲4個字節,偏移量爲0,sex 爲1個字節,偏移量爲0,所有數據項計算結束,當前結構體大小爲5,整體對齊時在 sex 之後填充3個字節,stuB爲8個字節。

stuA,、stuB雖然數據項的大小相同,但是基本數據項stuA 爲一個字節的char ,stuB 爲四個字節的 int。


在實際的使用過程中還需要注意一下,不被sizeof計算的問題:

struct stuC//4
	{
		int num;//4
		static int sex;//1
	};
sizeof()只計算棧中分配的大小,而sex爲靜態變量是存放在全局數據區,不計算在內。stuC 中 num 爲4個字節,偏移量爲0,

當前結構體大小爲4,不填充,stuC爲4個字節。

聯合體(union):也叫共用體,幾個不同的變量共同佔用一段內存的結構。

聯合體中的所有成員是共享一段內存的,因此每個成員的存放首地址相對於於聯合體變量的基地址的偏移量爲0,即所有成員的首地址都是一樣的。
同一時間只能存儲1個被選擇的變量,對其他成員變量賦值會覆蓋原變量。
因此,聯合體的大小應爲 
1.容納下最大數據項的大小;
2.能被所有的基本數據類型都能整數。
typedef union U//12
{  
    char arr[9];//9
    int num;//4
}U; 
U 中 arr 爲9個 字節大小,num 爲4個字節大小,因此 U 的大小爲12個字節。

類(class):用戶自定義類型,每個類中包含數據說明和操作數據函數。

關於類的內存大小,需要注意:
1.虛函數,編譯器需要爲類構建虛函數表,類中需要存儲一個指針指向虛函數表的首地址;
2.靜態成員函數,類的所有實例共享,不被sizeof計算在內;
3.普通函數或靜態普通函數,都存儲在棧中,不被sizeof計算在內;
class A //12
{
    public:
            virtual void funa();
            virtual void funb();//4
            void func();
            static void fund();
            static int si;
    private:
            int num;//4
            char sex;//1
};

根據內存對齊規則,funa() 和 funb()會構建虛函數表的首地址,4個字節大小,偏移量爲0,func()和fund()存儲在棧中,不被sizeof()計算,
si 爲靜態成員函數,所有實例共享不被sizeof()計算,num 爲4個字節,偏移量爲0,sex爲1個字節,偏移量爲0,數據項計算結束,當前類的大小爲9,
整體對齊時,sex之後填充3個字節,A的大小爲12個字節。


參考文獻1:C語言結構體大小計算

參考文獻2:C語言sizeof求結構體大小問題彙總


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章