2014-01-13 53 views
2

有人可以請解釋這段代碼的輸出嗎?sizeof(struct)奇怪的輸出在C++

#include <iostream> 
using namespace std; 

struct Yo{ 
    char sex; 
    int a; 
}; 

int main() { 
    Yo c; 
    cout<<sizeof(c.sex); 
    cout<<endl<<sizeof(c.a); 
    cout<<endl<<sizeof(c); 
    return 0; 
} 

輸出:1 4 8

如何是結構8的大小?

+5

這就是所謂的內存對齊。 – 2014-01-13 16:46:03

+2

這就是結構填充是什麼! –

+1

由於填充。你可以確定結構的大小,你應該使用'#pragma pack()'作爲[末尾](http://en.wikipedia.org/wiki/Data_structure_alignment#Data_structure_padding) – 2014-01-13 16:50:08

回答

1

由於結構填充(又稱內存對齊)。這個對齊必須是2的冪(C11使得@ KeithThompson在6.2.8p4中明確表示),並且由於結構的總大小是5,所以4的最接近倍數是8,所以它給出了8,這也是因爲對齊必須是兩個冪。

您可以使用#pragma pack以獲得確切的大小。

#pragma pack(push, 1) /* set alignment to 1 byte boundary */ 
struct A { 
    char s; 
    int a; 
}; 
#pragma pack(pop) // restore to default 

警告:#pragma pack不在標準C,也不是該結構需要4字節對齊的假設。正如@凱斯湯普森所言。 「

」類型的大小必須是其對齊的倍數,但大小不一定是2的乘方。例如,假設4字節的int,像struct { int a, b; char d; }這樣的結構將可能具有4的對齊和12的大小。大小是對齊的最接近的倍數,而不是2的最接近的功率。「 - @KeithThompson

包裝對於減少內存,當你有一個充滿整數的結構,固定的字符長度等等時很有用。我不知道它是否適合用在指針上,但我沒有看到它有用時使用指針(例如結構中的void *)。

閱讀全文here

+0

結構尺寸不一定是2的冪。在這裏,它只是填充 – Doraj

+0

對齊必須,對不起。 – 2014-01-13 16:56:39

+0

我的答案似乎仍然是錯誤的:將int放在結構中的char之前,並且sizeof將返回5:僅僅通過知道每個元素的大小的總和就找不到結構的sizeof – Doraj

4

這是內存對齊。

struct Yo{ 
    char sex; // Takes up 1 byte + 3 for padding 
    int a;  // Takes up 4 bytes 
}; 

sexa之間的三個字節將不會被使用,因爲編譯器有更好的表現比對它們。因此,sex使用1個字節的空間結束,而成員變量之後的三個字節用作填充以確保int a具有4的地址倍數(它是4字節對齊的)。

+0

說'性'使用4個字節的空間是錯誤的。填充不是任何成員的一部分。 –

+1

@GuilhermeBernal:足夠公平我的答案已更新。 –