David
David

Reputation: 1017

New stops my object working correctly

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?

Upvotes: 1

Views: 209

Answers (2)

David
David

Reputation: 1017

Crash after m = XMMatrixIdentity() - aligment memory in classes?

This topic covers the answer to my problem. I eventually tracked it down to XMMATRIX causing crashes with new due to memory alignment.

Here's a shortened version of the problem:

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;
}

Chances are matrix_test will complete but it will crash before pointer will complete.

Upvotes: 0

digit plumber
digit plumber

Reputation: 1172

It seems you have a good constructor, but bad/insufficient (default) assignment operator and bad/insufficient (default) copy constructor.

Let's see why some parts of your code works but some not:

//threed_cube_vec[0].draw(threeD, camera, d3dContext_); // doesnt work!!!

It tells you what's in threed_cube_vec[0] is a bad/corrupted object.

ThreeD_Cube test  = threed_cube_vec[0]; // But, if I copy it...

In this line, (for some reason) firstly the constructor is called, which gives you a good object. Then the "=" is called, partially the object is modified, but the object is still good since it was already good before the "="

ThreeD_Cube* test = &threed_cube_vec[0];

As for a pointer, it is the essentially object threed_cube_vec[0] itself, so still corrupted.

ThreeD_Cube test  = threed_cube_vec[0];
vector<ThreeD_Cube> test2;
test2.push_back(test);
test2[0].draw(threeD, camera, d3dContext_);

This does not fixed the problem as you said. "test" is a good object, but when you push_back(test) into test2, a copy is pushed back [if you change it to test2.push_back(std::move(test) , the problem could be gone]. Since the copy constructor is incomplete, the object in test2[0] is corrupted. Similar scenario happens with your map.

Conclusion: if an object is originated from the constructor, you get a good object; if an object is originated from a copy constructor, it is corrupted.

A quick test you can do: resize your vector after you declare it, the error should be gone temporarily.

Upvotes: 1

Related Questions