我不得不完全重写这个问题,因为我现在已经发现了很多这个问题。
背景:
我的程序正在directx11下绘制一些3d对象。我有一个类,包含绘制所需的3d对象所需的数据,指针和函数。一切都运作良好。我可以创建许多不同的3d对象并在任何我想要的地方绘制它们。太好了!
然后我需要将它们放在一个容器中并放入一个向量中,这样我就不必手动创建每个对象,这就是麻烦开始的地方;它会在5左右的时间内崩溃1次。
Unhandled exception at 0x00C308C1 in SpritesNTextN3D.exe: 0xC0000005: Access violation reading location 0xFFFFFFFF.
使用矢量和地图时崩溃了。我继续这一调查,并尝试使用指针和新的:
ThreeD_Cube* threed_cube_p;
threed_cube_p = new ThreeD_Cube;
当我运行其绘制功能时,这也导致它崩溃。
threed_cube_p->draw(threeD, camera, d3dContext_mp);
但是,如果创建为标准对象:
ThreeD_Cube threed_cube_;
绘制功能永远不会崩溃。
threed_cube_-.draw(threeD, camera, d3dContext_mp);
同样,创建指向threed_cube_的指针按预期工作。
问题:
默认构造函数不是新的做法。有什么我应该考虑解决这个问题吗?
答案 0 :(得分:1)
看起来你有一个好的构造函数,但是错误/不足(默认)赋值运算符和错误/不足(默认)复制构造函数。
让我们看看为什么你的代码的某些部分可以工作,但有些部分却没有:
//threed_cube_vec[0].draw(threeD, camera, d3dContext_); // doesnt work!!!
它告诉你threed_cube_vec [0]中有什么是坏/损坏的对象。
ThreeD_Cube test = threed_cube_vec[0]; // But, if I copy it...
在这一行中,(由于某种原因)首先调用构造函数,它为您提供了一个好的对象。然后调用“=”,部分修改了对象,但是对象仍然很好,因为在“=”之前它已经很好了
ThreeD_Cube* test = &threed_cube_vec[0];
至于指针,它本质上是对象threed_cube_vec [0]本身,所以仍然被破坏。
ThreeD_Cube test = threed_cube_vec[0];
vector<ThreeD_Cube> test2;
test2.push_back(test);
test2[0].draw(threeD, camera, d3dContext_);
这并没有像你说的那样解决问题。 “test”是一个很好的对象,但是当你将push_back(test)推入test2时,副本会被推回[如果你把它改成test2.push_back(std :: move(test),问题可能会消失]。复制构造函数不完整,test2 [0]中的对象已损坏。类似的情况发生在你的地图上。
结论:如果一个对象来自构造函数,那么你会获得一个好的对象;如果对象源自复制构造函数,则它已损坏。
您可以进行快速测试:声明后调整矢量大小,错误应该暂时消失。
答案 1 :(得分:0)
Crash after m = XMMatrixIdentity() - aligment memory in classes?
本主题介绍了我的问题的答案。我最终将它跟踪到XMMATRIX,由于内存对齐而导致崩溃。
这是问题的缩短版本:
void matrix_test_pointer()
{
XMMATRIX* xmmatrix_p;
xmmatrix_p = new XMMATRIX;
*xmmatrix_p = XMMatrixIdentity(); // this is where it crashes
}
void matrix_test()
{
XMMATRIX xmmatrix;
xmmatrix = XMMatrixIdentity();
}
int main()
{
string wait;
matrix_test();
cout << "matrix_test() completed.\n";
matrix_test_pointer();
cout << "matrix_test_pointer() completed.\n"; // If it does you are lucky :)
cin >> wait;
return 0;
}
有机会完成matrix_test,但在指针完成之前它会崩溃。