2013-08-17 46 views
5

我有一個結構定義爲:爲什麼offsetof(member)等於sizeof(struct)?

struct smth 
{ 
    char a; 
    int b[]; 
}; 

當我打電話sizeofoffsetof在這個結構:

cout << sizeof(struct smth) << endl; 
cout << offsetof(struct smth, b) << endl; 

輸出是:

4 
4 

如何來時的大小stuct是4並且char使用1個字節,int數組的偏移量是4? 爲什麼會有某種填充? 此外,爲什麼不是int數組佔用任何空間?

+1

你的意思是'offsetof(struct smth,b)',對吧? –

+0

@CarlNorum是的,我喜歡。編輯。 – bugra

+2

它是C還是C++?他們是不同的。 –

回答

8

當stuct的大小是4並且char使用1個字節,int數組的偏移量是4時,怎麼會發生這種情況?爲什麼會有某種填充?

有填充因爲C標準允許它;編譯器通常會調整變量以提高性能。

此外,爲什麼不是第二個變量佔用任何空間(這似乎是這樣)?

這是一個C99靈活的數組成員 - 這就是它的全部要點。這樣做是爲了分配您的結構是這樣的:

struct smth *s = malloc(sizeof *s + 10 * sizeof s->b[0]); 

然後你不得不說的操作就如同b是一個10個元素的數組的結構。

+0

這種性能改進是否允許?只是好奇。 – bugra

+0

@ biox6,一些處理器加載指令只能從字對齊的地址加載字。如果你在一個未對齊的地址有一個單詞,你需要分別加載每個字節並重新組合。 –

+0

您的分配語句不考慮對齊限制。一般來說,它將無法分配正確的內存量。你應該使用'struct smth * s = malloc(offsetof(struct smth,b [10]));'來分配一個正確大小的結構。 – IInspectable

3

由於成員b的大小爲零,編譯器在ab成員之間添加了填充,因此b位於「字」邊界上。但是,如果我沒有記錯在一個像這樣的結構中有一個靈活的數組只是有效的C,而不是C++,除非作爲編譯器擴展。

+0

這是'int b []'相當於int * b嗎? – Light

+2

不,不是。 'int * b'會使'sizeof(smth)'變大,而多餘的空間就是要存儲一些int變量的地址。相反,'int b []'表示結構應該動態分配一些(編譯時未知的)整數作爲一個單獨的內存塊。 – mity

+0

@mity你如何給變量'b'賦值,你能給我賦值語句嗎? – Light

2

由於OP評論說,問題是C++:

struct smth 
{ 
    char a; 
    int b[]; 
}; 

b[]數組是用C++無效。數組必須具有固定大小。可變長度數組僅在C99中有效。

假設您的編譯器支持它作爲擴展名,則數組b[]的大小爲零,這使得該結構僅包含一個char成員。 struct中的填充規則起作用,將struct填充爲單詞,即在您的計算機中爲4個字節。

相關問題