1. sizeof 是運算符,而不是函數。
2. 當sizeof 的對象是表達式時,求的大小是表達式返回值的類型大小,但並不計算表達式的值,比如:
1 char c = 1; 2 int i = 2; 3 cout << sizeof(c + i) << endl; 4 cout << sizeof(c = c + i) << endl;
前者c + i會隱式類型轉化為int類型(類型提升),因此返回4(32位系統), 而后者雖然運算時也是轉化為int,但賦值給c時又會轉化為char,因此返回的是1。
3. 如果對象是函數,則返回函數返回值類型大小,如:
1 long long foo() 2 { 3 cout << "foo() has been called" << endl; 4 return 0; 5 } 6 7 int main(int argc, char **argv) 8 { 9 cout << sizeof(foo()) << endl; 10 return 0; 11 }
執行后輸出8, 不會輸出 foo() has been called.說明函數沒有真正執行,而只是判斷了下返回類型。
4. 當sizeof的對象是數組時,返回數組總大小,而當對象是指針時,返回指針本身的大小,而不是指示內存空間的大小。因為指針本身就是一個無符號整型數, 因此int *p ,sizeof(p)返回的大小是sizeof(void *), 32 位系統返回4,即32位。但注意當數組名作為實參傳入函數時,會自動轉化為指針類型,如下:
1 void foo(int a[]) 2 { 3 cout << sizeof(a) << endl; /* 4 */ 4 } 5 int main(int argc, char **argv) 6 { 7 int a[] = {1, 2, 3, 4}; 8 int *p = a; 9 cout << sizeof(a) << endl; /* 16 */ 10 cout << sizeof(p) << endl; /* 4 */ 11 foo(a); 12 return 0; 13 }
5. sizeof 無法獲取動態分配的內存大小,即使用malloc動態的分配內存,無法使用sizeof獲取其大小。
6. 注意c_style字符串末尾有一個\0結束符,也需要占一個char空間,因此sizeof("1") 返回2。而strlen返回的是字符數,不包括\0結束符。
7. 理論上一個結構體所占空間是所有成員的大小總和,但由於考慮到對齊問題,會有填充字節。
struct node1 { int a; int b; char c; char d; }; struct node2 { int a; char b; int c; char d; };
node1大小為12字節, node2大小為16字節。
結構體后面的動態數組,即不指定大小的數組,sizeof 時不包括動態數組的大小,即
1 struct node 2 { 3 int a; 4 char c; 5 int d[]; 6 };
返回依然是8。
8. 類的大小:
(1). 空類的大小。空類型實例中不包含任何信息,應該大小為0. 但是當我們聲明該類型的實例的時候,它必須在內存中占有一定的空間,否則無法使用這些實例。至於占用多少內存,由編譯器決定。g++中每個空類型的實例占1字節空間。注意空struct即空類,這就是為什么c++的空struct占1個字節的原因。
(2). 構造函數、析構函數、成員函數調用時只需知道函數地址即可,而這些函數的地址之與類型相關,而與具體的實例無關,因此不會在實例中額外添加任何信息。
(3). 靜態數據成員放在全局數據成員中,它不占類實例大小,多個類實例只有一個實體。可以看作是一種特殊的全局變量。
(4). 類的非靜態數據成員和struct類似,也需要對齊,可能需要字節填充。
(5). 如果一個類中有虛函數,則該類型會生成一個虛函數表,並在該類型的每一個實例中添加一個指向虛函數表的指針,因此類大小必須加上一個指針所占的空間。如果是普通繼承,子類和基類共享這個指針。
1 class A 2 { 3 public: 4 static int a; 5 static char c; 6 A(){}; 7 ~A(){}; 8 void foo(){}; 9 }; 10 // 類A的大小為1字節,等於空類大小,靜態數據成員a、c和成員函數都不占類的大小。 11 12 class B 13 { 14 public: 15 int a; 16 char c; 17 A(){}; 18 ~A(){}; 19 void foo(){}; 20 }; 21 // 類B的大小為8字節 22 23 class C 24 { 25 public: 26 int a; 27 char c; 28 A(){}; 29 ~A(){}; 30 void foo(){}; 31 void virtual bar(){}; 32 }; 33 // 類C的大小為12。數據成員8,加上指向虛擬函數表的指針。
(感謝http://www.cnblogs.com/zhangyz/articles/4736758.html)