2012-12-27 48 views
4

可能重複:
Why does ‘sizeof’ give wrong measurement?C++的sizeof給出了不可預知的結果

我有一個名爲CBUFFER_PEROBJECT結構:

struct CBUFFER_PEROBJECT 
{ 
    D3DXMATRIX Final; 
    D3DXMATRIX Rotation; 
}; 

而在另一個類我這樣做:

... 
bd.ByteWidth = sizeof(CBUFFER_PEROBJECT); 
... 

我發現D3DXMATRIX的大小是64,所以64 + 64 = 128(對吧?)。但我的編譯器是在捉弄我(的Visual C++),因爲我在調試程序時,bd.ByteWidth成了132,所以我去了即時窗口(Visual Studio中),和類型:

sizeof(D3DXMATRIX) + sizeof(D3DXMATRIX) 

而結果是:

128 

但bd.ByteWidth變成132,當我鍵入以下到 「即時窗口」:

sizeof(CBUFFER_PEROBJECT) 

它給我:

128 
+5

64 * 64不是128. –

+1

什麼問題? – 0x499602D2

+1

64 * 64是4096 – 0x499602D2

回答

2

有時編譯器正在評估結構聲明時,它們會在字段之間添加填充字節。這是因爲某些類型在對齊到長度爲倍數的內存地址時性能更好。

我甚至可以說很有可能你不會在眼前的窗口看到這種效果。

鑑於這些理由,這是一個重複的問題。你可以在這裏得到更深入的答案:Why isn't sizeof for a struct equal to the sum of sizeof of each member?

6

對,你很困惑D3DMATRIXD3DXMATRIX(注意在第二種類型中多餘的X)。第一個是16浮點值的純矩陣(正好64字節)。後者是一個類,它顯然在結構中有4個字節的額外數據。也許是一個vtable或其他一些。

如果您將代碼編譯爲C而不是C++,則其大小將與提供後者結構的頭文件相同,然後執行typedef D3DMATRIX D3DXMATRIX;

參見:D3DXMATRIXD3DMATRIX

編輯:這是一個有點像老笑話關於軍隊說:「如果地圖與現實不匹配,地圖是正確的」。在這種情況下,如果你不同意編譯器,你錯了。編譯器在計算大小時始終是正確的。理解爲什麼編譯器得到這個數字,那麼這就是另一回事了......通常通過比較結構中的預期偏移與實際發生的事情,並理解是什麼引起的「差距」來解決。

+4

代碼中使用的D3DMATRIX在哪裏? – dupersuper

+0

它不是。 D3DXMATRIX是 - 但由於它是一個類,它是一個合理的解釋佔用額外的空間。至少在我的經驗。 –

+1

更合理的解釋是結構對齊。 –

2

你不能計算結構的大小,只是計算它的成員大小,因爲在結構中它也存儲了一些額外的信息(對於程序員不可見)。這就是爲什麼你得到132而不是128.

+1

此「額外信息」有時可能是調試信息,但它很可能來自結構對齊。 –

1

在這種情況下,最好假定編譯器是正確的。這很可能意味着您的項目中有兩個不同的定義CBUFFER_PEROBJECT,其定義略有不同。編譯器認爲定義A的大小爲132,而調試器正在查看大小爲128的定義B.您可以通過在每個源文件中創建包含sizeof(CBUFFER_PEROBJECT)的值的全局變量來測試該定義。然後您可以在調試器中檢查這些全局變量以查看它顯示的內容。

另一種可能性當然是你的記憶被覆蓋,而不是由你認爲設置它的行設置。在這種情況下,Purify或valgrind可以幫助您追蹤內存問題。

1

您可以使用隱藏的visual studio編譯器切換到/d1reportSingleClassLayoutSomeType來告訴您編譯器佈局是什麼。按照鏈接閱讀如何使用開關。

我試過它爲你的示例代碼,但我沒有'D3DXMATRIX'類型。我有「D3DMATRIX」所以我想這一點,得到了:

1> class CBUFFER_PEROBJECT size(128): 
1>  +--- 
1> 0 | _D3DMATRIX Final 
1> 64 | _D3DMATRIX Rotation 
1>  +--- 

所以如果你使用的開關應該能夠告訴你,你的結構的準確佈局。