1

I've had to completely rewrite this problem as I've found out a lot more about it now.

Background:

My programme is drawing some 3d objects under directx11. I have a class that contains the data, pointers, and functions needed to draw the required 3d objects. Everything was working well. I could create many different 3d objects and draw them wherever I wanted. Great!

Then I needed to put them in a container and into a vector so I didn't have to create each object manually, this was where the trouble started; it would crash 1 time in 5 or so.

Unhandled exception at 0x00C308C1 in SpritesNTextN3D.exe: 0xC0000005: Access violation reading location 0xFFFFFFFF.

It crashed when using vectors and maps. I continued this line of enquiry and tried using a pointer and new:

ThreeD_Cube* threed_cube_p;
threed_cube_p = new ThreeD_Cube;

This also caused it to crash when I ran its draw function.

threed_cube_p->draw(threeD, camera, d3dContext_mp);

However if created as a standard object:

ThreeD_Cube threed_cube_;

The draw function never crashes.

threed_cube_-.draw(threeD, camera, d3dContext_mp);

Likewise, creating a pointer to threed_cube_ works as expected.

Question:

What is new doing that the default constructor isn't. Is there anything I should be looking at to resolve this problem?

4

2 に答える 2

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" は良いオブジェクトですが、test2 に push_back(test) すると、コピーがプッシュバックされます [これを test2.push_back(std::move(test) に変更すると、問題はなくなる可能性があります]。コピー コンストラクターが不完全で、test2[0] のオブジェクトが壊れています。マップでも同様のシナリオが発生します。

結論: オブジェクトがコンストラクターから生成された場合、適切なオブジェクトが得られます。オブジェクトがコピー コンストラクターから生成された場合、そのオブジェクトは破損しています。

実行できる簡単なテスト: ベクトルを宣言した後にサイズを変更すると、エラーは一時的に解消されるはずです。

于 2013-07-11T20:26:12.820 に答える
0

m = XMMatrixIdentity() 後のクラッシュ - クラス内のアラインメント メモリ?

このトピックは、私の問題に対する答えをカバーしています。私は最終的にそれをXMMATRIXまで追跡し、メモリの配置が原因でnewでクラッシュを引き起こしました。

問題の短縮版は次のとおりです。

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 は完了する可能性がありますが、pointer が完了する前にクラッシュします。

于 2013-07-18T04:36:00.183 に答える