C++Sizeof会产生不可预测的结果

C++ Sizeof gives unpredictable results

本文关键字:结果 不可预测 C++Sizeof      更新时间:2023-10-16

可能重复:
为什么"sizeof"给出错误的度量?

我有一个名为CBUFFER_PEROBECT的结构:

struct CBUFFER_PEROBJECT
{
    D3DXMATRIX Final;
    D3DXMATRIX Rotation;
};

在另一个课堂上,我这样做:

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

我发现D3DXMIX的大小是64,所以64+64=128(对吗?(。但我的编译器在耍我的花招(Visual C++(,因为当我调试程序时,bd.ByteWidth变成了132,所以我转到即时窗口(Visual Studio(,键入:

sizeof(D3DXMATRIX) + sizeof(D3DXMATRIX)

结果是:

128

但是bd.ByteWidth变成了132,当我在"立即窗口"中键入以下内容时:

sizeof(CBUFFER_PEROBJECT)

它给了我:

128

没错,您混淆了D3DMATRIXD3DXMATRIX(请注意第二种类型中的额外X(。第一个是一个由16个浮点值组成的纯矩阵(因此正好是64个字节(。后者是一个类,显然在结构中的某个位置有4个字节的额外数据。也许是vtable或诸如此类的。

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

参见:D3DXMIX和D3DMIX

编辑:这有点像军方的老笑话"如果地图和现实不匹配,地图就是对的"。在这种情况下,如果你不同意编译器的观点,那你就错了。编译器在计算大小时总是正确的。理解编译器为什么得到这个数字,好吧,那是另一回事。。。通常通过将结构中的预期偏移与实际发生的偏移进行比较,并了解是什么导致了"间隙"来解决。

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

我甚至想说,你很可能在短期内看不到这种影响。

鉴于这些理由,这是一个重复的问题。你可以在这里得到一个更深入的答案:为什么不是';t结构的sizeof等于每个成员的sizeof之和?

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

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

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

您可以使用隐藏的visual studio编译器开关/d/reportSingleClassLayoutSomeType来告诉您编译器布局是什么。按照链接阅读如何使用开关。

我为您的示例代码尝试过,但我没有类型"D3DXMIX"。我确实有"D3DMIX",所以我尝试了一下,得到了:

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

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