C/C++ sizeof函數解析——【結構體】【類】
轉載自:https://www.cnblogs.com/0201zcr/p/4789332.html
C/C++中不同數據類型所占用的內存大小
32位 64位
char 1 1
int 4 大多數4,少數8
short 2 2
long 4 8
float 4 4
double 8 8
指針 4 8
(單位都為字節)
結構體(struct):比較復雜,對齊問題。
聯合(union):所有成員中最長的。
枚舉(enum):根據數據類型。
結構體sizeof
先介紹一個相關的概念——偏移量。偏移量指的是結構體變量中成員的地址和結構體變量地址的差。結構體大小等於最後一個成員的偏移量加上最後一個成員的大小。顯然,結構體變量中第一個成員的地址就是結構體變量的首地址。因此,第一個成員i的偏移量為0。第二個成員c的偏移量是第一個成員的偏移量加上第一個成員的大小(0+4),其值為4;第三個成員j的偏移量是第二個成員的偏移量加上第二個成員的大小(4+1),其值為5。
然而,在實際中,存儲變量時地址要求對齊,編譯器在編譯程序時會遵循兩條原則:
(1)結構體變量中成員的偏移量必須是成員大小的整數倍(0被認為是任何數的整數倍)
(2)結構體大小必須是所有成員大小的整數倍,也即所有成員大小的公倍數。
sizeof計算嵌套的結構體大小
對於嵌套的結構體,需要將其展開。對結構體求sizeof時,上述兩種原則變為:
(1)展開後的結構體的第一個成員的偏移量應當是被展開的結構體中最大的成員的整數倍。
(2)結構體大小必須是所有成員大小的整數倍,這裏所有成員計算的是展開後的成員,而不是將嵌套的結構體當做一個整體。
類的sizeof
1空類
class A {};
1
大小為1。
類的實例化就是給每一個實例在內存中分配一塊地址。空類被實例化時,會由編譯器隱含的添加一個字節。所以空類的size為1。
2 虛函數
當C++類中有虛函數的時候,會有一個指向虛函數表(V-table)的指針,所有的虛函數都在這個表中。指針大小為4,所以size為4。
為了效率問題,編譯器(gcc 和 微軟)一般會把虛指針放在類的內存空間的最前面的位置,不管虛函數聲明的位置。考慮對齊,大小都是 4 +1+1+2 = 8.
3 靜態數據成員
靜態數據成員被編譯器放在程序的一個global data members中,它是類的一個數據成員,但不影響類的大小。不管這個類產生了多少個實例,還是派生了多少新的類,靜態數據成員只有一個實例。靜態數據成員,一旦被聲明,就已經存在。 考慮到數據對齊, 最終是8字節。
4 普通成員函數
class A
{
public:
void fun() {};
};
大小為1。
類的大小與構造函數,析構函數,普通成員函數無關。
5 普通單繼承
大小分別為4 和 8。 可以看到普通的繼承就是基類的大小+派生類自身的大小。註意數據對齊。
註意:類的數據成員按其聲明順序加入內存,無訪問權限無關,只看聲明順序。
6 含虛函數的單繼承
7 虛單繼承
8 普通多繼承
9 虛函數多繼承
1 class A 2 { 3 virtual void fun() {} 4 }; 5 6 class B 7 { 8 virtual void fun2() {} 9 }; 10 class C : public A, public B 11 { 12 public: 13 virtual void fun3() {} 14 };
4 4 8
類A一個虛函數表,類B一個虛函數表,類C繼承了兩個虛函數表,並把自己的虛函數寫在了繼承順序中第一個虛函數表中。
10 虛繼承
作者:zhengjihao
來源:CSDN
原文:https://blog.csdn.net/zhengjihao/article/details/77825269
版權聲明:本文為博主原創文章,轉載請附上博文鏈接!
C/C++ sizeof函數解析——【結構體】【類】