我有一个名为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
答案 0 :(得分:6)
是的,你让D3DMATRIX
和D3DXMATRIX
感到困惑(注意第二种类型的额外X)。第一个是16个浮点值的纯矩阵(恰好是64个字节)。后者是一个类,它显然在结构中的某处有4个字节的额外数据。也许是一个vtable或一些这样的。
如果将代码编译为C而不是C ++,则大小将相同,因为提供结构后者的头文件会typedef D3DMATRIX D3DXMATRIX;
。
请参阅:D3DXMATRIX和D3DMATRIX
编辑:这有点像关于军方的老笑话“如果地图和现实不匹配,地图是对的”。在这种情况下,如果您不同意编译器,那就错了。在计算大小时,编译器始终是正确的。理解为什么编译器得到了这个数字,那么这是另一回事......通常通过将预期的偏移量与实际发生的结果进行比较来解决,并了解什么,如果有什么导致“差距”。
答案 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> +---
因此,如果您使用开关,则应该能够告诉您结构的确切布局。