C++Sizeof会产生不可预测的结果
C++ Sizeof gives unpredictable results
可能重复:
为什么"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
没错,您混淆了D3DMATRIX
和D3DXMATRIX
(请注意第二种类型中的额外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> +---
因此,如果你使用开关,它应该能够告诉你结构的确切布局。
- 不可预测的C++睡眠/等待行为
- 超过 N 时出现不可预测的位移结果
- DirectShow CSourceStream::FillBuffer 暂停和查找后对第一帧的不可预测的调用数
- 多线程文件 IO 程序在线程数增加时行为不可预测
- 使用 std::find 查找从二进制文件中读取的字符并转换为 std::vector 中的 std::string<string> 会产生这种不可预测的行为?
- std::sleep_for在Windows 10上的不可预测行为
- 不可预测的文件描述符泄漏
- 循环程序的行为是不可预测的
- C++中不可预测的输出
- 当来自外部库的线程不可预测地崩溃我的应用程序时,我该怎么办
- 不可预测的伪RNG
- C++ 自定义运算符(+=) 的行为方式不可预测
- 如何优化间接基数排序?(又名如何优化不可预测的内存访问模式)
- 修复不可预测的崩溃
- 不可预测的指针行为
- wxWidgets 不可预测的 Seg 故障
- 当 cin.getline() 的第二个参数大于数组长度时,不可预测的字符串长度
- 使用Dijkstra算法找到最佳路径的不可预测的结果
- Pthread条件变量不可预测的结果
- C++Sizeof会产生不可预测的结果