http://blog.csdn.net/dotnet_2007/archive/2009/04/29/4135562.aspx
(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>。