2012-10-02 104 views
6

這是一個簡單的問題。先編碼。C++ sizeof與布爾

struct A { 
    int x; 
}; 
struct B { 
    bool y; 
}; 
struct C { 
    int x; 
    bool y; 
}; 

在主函數中,我稱之爲

cout << " bool : " << sizeof(bool) << 
    "\n int : " << sizeof(int) << 
    "\n class A : " << sizeof(A) << 
    "\n class B : " << sizeof(B) << 
    "\n class C : " << sizeof(C) << "\n"; 

,其結果是

bool : 1 
int : 4 
class A : 4 
class B : 1 
class C : 8 

爲什麼C類8而不是5的大小? 請注意,這是用MINGW 4.7/Windows 7/32位機器中的gcc編譯的。

+0

這就是所謂的填充。 – Marlon

+0

@Marlon所以,填充的主要目的是什麼? – Sungmin

+0

@Sungmin:想想數組。 –

回答

6

的集合體的排列回答是,其嚴格的構件(具有最大對齊要求的成員)的。換句話說,結構的大小是其最嚴格(具有最大對齊要求)成員的對齊的倍數。

struct D 
{ 
    bool a; 
    // will be padded with char[7] 
    double b; // the largest alignment requirement (8 bytes in my environment) 
}; 

的結構的大小以上將是16個字節,因爲16是8的倍數。在您的例子最嚴格的類型是int對準4個字節。這就是爲什麼該結構被填充爲8個字節。我會舉另一個例子:

struct E 
{ 
    int a; 
    // padded with char[4] 
    double b; 
}; 

上面的結構的大小是16. 16是8的倍數(在我的環境中雙重對齊)。

我寫了一篇博客文章內存對齊對於更詳細的解釋 http://evpo.wordpress.com/2014/01/25/memory-alignment-of-structures-and-classes-in-c-2/

+0

這不是最長的類型;它是對齊「最嚴格」(即最長)的類型的對齊方式。在許多ABI中,例如,double的長度爲8個字節,但只有4個字節對齊。 (理論上講,它應該是所有路線的LCM,但是標準要求「每個定線值應該是兩個非負整數冪」(3.11,第4段),所以你可以選擇最長的一個。) – rici

2

將結構對齊到一個單詞的大小,這裏是4個字節。

+0

我可以再問一次嗎?對齊結構的原因是什麼? – Sungmin

+0

這不解釋對齊策略或可能是答案不完整。如果它對齊到4,那麼struct B也會是4個字節。但是,它的大小是1個字節。同樣在我的回答中,我證明了編譯器對齊了8個字節,而不是4。我的觀點是,它將結構的大小與它包含的最大類型的倍數對齊。這更好地解釋了它。 – evpo

-1

看看你的結構的定義,你有1個字節的值,後面跟着4個字節的整數。這個整數需要在4個字節的邊界上分配,這會迫使編譯器在你的1個字節布爾值之後插入一個3字節的填充。這使結構的大小爲8個字節。爲了避免這種情況,您可以更改結構中元素的順序。

對於兩個返回不同值的sizeof調用,你確定在這裏沒有輸入錯誤,並且沒有指針或不同類型或某個整數變量的大小。

通過羅希特夏爾J於struct size is different from typedef version?

+0

在我的情況下,改變struct C中元素的順序並不影響結果。 – Sungmin

+0

@Sungmin:成員的順序通常不會影響填充。考慮如果'int'必須對齊到一個4字節的邊界,它可以被命令爲'bool',padding,'int';或'int','bool',填充。請注意,在一個數組中,每個元素的位置都是'sizeof(type)'字節。 –

+0

@Sungmin:你說的沒錯。在這種情況下,改變順序不會改變'struct'的大小。 –