C ++ Sizeof给出了不可预测的结果

时间:2012-12-27 18:26:58

标签: c++ debugging visual-c++

  

可能重复:
  Why does ‘sizeof’ give wrong measurement?

我有一个名为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 个答案:

答案 0 :(得分:6)

是的,你让D3DMATRIXD3DXMATRIX感到困惑(注意第二种类型的额外X)。第一个是16个浮点值的纯矩阵(恰好是64个字节)。后者是一个类,它显然在结构中的某处有4个字节的额外数据。也许是一个vtable或一些这样的。

如果将代码编译为C而不是C ++,则大小将相同,因为提供结构后者的头文件会typedef D3DMATRIX D3DXMATRIX;

请参阅:D3DXMATRIXD3DMATRIX

编辑:这有点像关于军方的老笑话“如果地图和现实不匹配,地图是对的”。在这种情况下,如果您不同意编译器,那就错了。在计算大小时,编译器始终是正确的。理解为什么编译器得到了这个数字,那么这是另一回事......通常通过将预期的偏移量与实际发生的结果进行比较来解决,并了解什么,如果有什么导致“差距”。

答案 1 :(得分:2)

你不能只计算它的成员大小来计算结构的大小,因为在结构中它还存储了一些额外的信息(程序员看不到)。这就是为什么你得到132而不是128。

答案 2 :(得分:2)

有时,当编译器评估结构声明时,它们会在字段之间添加填充字节。这是因为某些类型在与其长度的倍数的内存地址对齐时表现更好。

我甚至说你很可能不会在即时窗口看到这种效果。

鉴于这些理由,这是一个重复的问题。您可以在此处获得更深入的答案:Why isn't sizeof for a struct equal to the sum of sizeof of each member?

答案 3 :(得分:1)

在这种情况下,最好假设编译器是正确的。这最有可能意味着您在项目中有两个不同的CBUFFER_PEROBJECT定义,定义略有不同。编译器认为定义A的大小为132,而调试器正在查看大小为128的定义B.您可以通过在每个源文件中创建包含sizeof(CBUFFER_PEROBJECT)值的全局变量来测试它。然后,您可以在调试器中检查这些全局变量以查看它显示的内容。

另一种可能性当然是你的记忆被覆盖了,而不是你认为正在设置它的行设置。在这种情况下,像Purify或valgrind这样的东西可以帮助你追踪内存问题。

答案 4 :(得分:1)

您可以使用隐藏的visual studio编译器切换到/d1reportSingleClassLayoutSomeType来告诉您编译器布局是什么。请点击链接阅读如何使用开关。

我尝试过你的示例代码,但我没有'D3DXMATRIX'类型。我确实有'D3DMATRIX',所以我试过了,得到了:

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

因此,如果您使用开关,则应该能够告诉您结构的确切布局。