(1)sizeof也可以對一個函數調用求值,其結果是函數返回類型的大小,函數並不會被調用。
(2)終於搞懂struct結構體內存分配問題了,結構體中各個成員字節對齊遵循以下幾個原則:
1.結構體每個成員相對於結構體首地址的偏移量(offset)都是(這個)成員大小的整數倍,如有需要編譯器會在成員之間加上填充字節(internal adding);
例如有以下一個結構體
struct ex {
int i;
char t;
int n;
}
第1個成員偏移量爲0,是int型成員大小4(假設這太機器的整型長度佔4個字節)的整數倍。
第2個成員 t 爲char型,他的大小爲1,首先假設在成員i和t之間沒有填充字節,由於i是整型,佔4個字節那麼在沒有填充之前,第2個成員t相對於結構體的偏移量爲4,他是t成員大小1的4倍,符合此條件,所以系統在給結構體第2個成員分配內存時,不會在i和t之間填充字節以到達對齊的目的。
當分配結構體第3個成員n時,首先發現是一個整型數據,大小爲4,沒有填充之前,n相對於結構體首地址偏移量爲:前面2個成員+填充字節=5,所以當系統發現5不是4(成員大小)的整數倍時,會在成員t之後(或者說n之前)填充3個字節,以使n的偏移量到達8而成爲4的整數倍。這樣這個結構體佔用內存情況暫時爲4+1+3+4。
2.結構體的總大小爲結構體最寬基本類型成員大小的整數倍,如有需要編譯器會在最末一個成員之後加上填充字節(trailing padding)。
上面的結構體內存分配以後還要看是否滿足此條件,假設在最末一個成員之後不需填充字節數,那麼這個結構體的大小爲12。而ex結構體中最寬基本類型成員爲int,大小爲4,12爲4的整數倍,所以無須再在最末一個成員之後加上填充字節了。所以sizeof(ex)=12;
如果一個結構體如下所示struct ex1{
int i;
char t;
int n;
char add;
}
那麼sizeof(ex1) =16;原因就是在最後一個成員之後填充了3個字節。
3.還有一個額外的條件:結構體變量的首地址能夠被其最寬基本類型成員的大小所整除;
4.對於結構體成員屬性中包含結構體變量的複合型結構體再確定最寬基本類型成員時,應當包括複合類型成員的子成員。但在確定複合類型成員的偏移位置時則是將複合類型作爲整體看待。
5總結出一個公式:結構體的大小等於最後一個成員的偏移量加上其大小再加上末尾的填充字節數目,即:
sizeof( struct ) = offsetof( last item ) + sizeof( last item ) + sizeof( trailing padding )
C/C++ 中已經提供了宏 offsetof 計算成員的偏移量。注意包含頭文件:C 是 <stddef.h>,C++ 是 <cstddef>。