4

重複の可能性:
「sizeof」が間違った測定値を与えるのはなぜですか?

私はCBUFFER_PEROBJECTと呼ばれる構造を持っています:

struct CBUFFER_PEROBJECT
{
    D3DXMATRIX Final;
    D3DXMATRIX Rotation;
};

そして別のクラスで私はこれを行います:

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

D3DXMATRIXのサイズは64なので、64 + 64 = 128(右?)であることがわかりました。しかし、プログラムをデバッグしているときにbd.ByteWidthが132になったため、コンパイラーは私(Visual C ++)でトリックを実行しているので、イミディエイトウィンドウ(Visual Studio)に移動して次のように入力しました。

sizeof(D3DXMATRIX) + sizeof(D3DXMATRIX)

そしてその結果は次のとおりです。

128

しかし、bd.ByteWidthは132になり、「イミディエイトウィンドウ」に次のように入力すると次のようになります。

sizeof(CBUFFER_PEROBJECT)

それは私に与えます:

128
4

5 に答える 5

6

そうです、あなたは混乱D3DMATRIXしていますD3DXMATRIX(2番目のタイプの余分なXに注意してください)。1つ目は、16個のfloat値(正確には64バイト)の単純な行列です。後者はクラスであり、構造のどこかに4バイトの追加データがあることは明らかです。おそらくvtableかそのようなものです。

コードをC++ではなくCとしてコンパイルすると、サイズは同じになります。これは、後者の構造を提供するヘッダーファイルが行うためtypedef D3DMATRIX D3DXMATRIX;です。

参照:D3DXMATRIXおよびD3DMATRIX

編集:これは、「地図と現実が一致しない場合、地図は正しい」という軍隊に関する古いジョークに少し似ています。この場合、コンパイラに同意しないと間違っています。サイズを計算するとき、コンパイラは常に正しいです。コンパイラがその数を取得した理由を理解することは、別の問題です...通常、構造への予想されるオフセットを実際に発生するものと比較し、何かが「ギャップ」を引き起こした場合はそれを理解することによって解決されます。

于 2012-12-27T18:35:09.837 に答える
2

構造体には追加情報も格納されているため(プログラマーには表示されないため)、構造体のメンバーサイズを数えるだけで構造体のサイズを計算することはできません。そのため、128ではなく132を取得します。

于 2012-12-27T18:37:43.090 に答える
2

コンパイラが構造体宣言を評価しているときに、フィールド間にバイトのパディングを追加することがあります。これは、一部のタイプは、長さの倍数であるメモリアドレスにアラインメントするとパフォーマンスが向上するためです。

すぐにこの効果が見られない可能性が非常に高いと言っても過言ではありません。

これらの理由を考えると、これは重複した質問です。ここで、より詳細な回答を得ることができます。構造体のsizeofが、各メンバーのsizeofの合計と等しくないのはなぜですか。

于 2012-12-27T18:44:51.617 に答える
1

この場合、コンパイラが正しいと想定するのが最善です。これが最も可能性の高い意味はCBUFFER_PEROBJECT、プロジェクトに2つの異なる定義があり、定義がわずかに異なることです。コンパイラーは、デバッガーがサイズ128の定義Bを調べている間、定義Aのサイズは132であると見なします。これはsizeof(CBUFFER_PEROBJECT)、各ソースファイルの値を含むグローバル変数を作成することでテストできます。次に、デバッガーでこれらのグローバルを調べて、何が表示されるかを確認できます。

もう1つの可能性は、もちろん、メモリが上書きされ、設定していると思われる行によって設定されていないことです。その場合、Purifyやvalgrindのようなものが、メモリの問題を突き止めるのに役立ちます。

于 2012-12-27T19:45:32.973 に答える
1

/ d1reportSingleClassLayoutSomeTypeへの非表示のVisualStudioコンパイラスイッチを使用して、コンパイラのレイアウトを通知できます。リンクをたどって、スイッチの使用方法を確認してください。

サンプルコードで試してみましたが、タイプが「D3DXMATRIX」ではありません。私は「D3DMATRIX」を持っているので、それを試してみました:

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

したがって、スイッチを使用する場合は、構造体の正確なレイアウトを教えてくれるはずです。

于 2012-12-27T20:47:30.813 に答える