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

£可爱£侵袭症+ 提交于 2019-11-28 07:20:52

问题


I was looking at the tutorials in DirectX SDK. Tutorial 5 works fine, but after I have copied and separated the code to my own classes, I got strange error during launching my application.

The line is:

g_World1 = XMMatrixIdentity();

Because of it, I got error in xnamathmatrix.int operator= which looks like that:

XMFINLINE _XMMATRIX& _XMMATRIX::operator=
(
    CONST _XMMATRIX& M
)
{
    r[0] = M.r[0];
    r[1] = M.r[1];
    r[2] = M.r[2];
    r[3] = M.r[3];
    return *this;
}

And the error message is:

Access violation reading location 0xffffffff

I have read somewhere that it could be caused by something connected to XMFLOAT4X4 / XMMATRIX:

Have you considered using XMFLOAT4X4 to store the matrix, and only using XMMATRIX?

But I think I already use XMMATRIX.

MyClass.h:

private:
    XMMATRIX g_World1;

MyClass.cpp:

void init(){
   g_World1 = XMMatrixIdentity();
}

I don't think I should change XMMATRIX g_World1; to XMFLOAT4X4 g_World1, because it produces errors like:

error C2679: binary '=' : no operator found which takes a right-hand operand of type 'XMMATRIX' (or there is no acceptable conversion)


回答1:


XMVECTOR and XMMATRIX are the 'register proxy' types. You can use them safely as types for the Xbox 360, Xbox One, and Windows x64 platforms as they all natively have 16-byte alignment for the data on the stack and allocated on the heap.

Using them for Windows 32-bit or Windows RT/ARM takes more effort since the native alignment is les than 16-bytes. One approach is the technique used by DirectX Tool Kit... it uses the pImpl idiom and the pImpl internal classes are explicitly allocated with 16-byte alignment which is where XMVECTOR and XMMATRIX types are used directly. Another approach is to use all the various 'storage' types like XMFLOAT4 and XMFLOAT4X4.

Note: the DirectXMath programmer's guide covers this. It's not a long document to read, and it's packed with a lot of hints and recommendations.

PS: There's a version of the standard Direct3D tutorials for Win32 desktop on MSDN Code Gallery that does not require the DirectX SDK... it just uses the Windows 8.x SDK included with VS 2012 or VS 2013.enter link description here




回答2:


Since XMMATRIX represents a 16-byte aligned 4x4 matrix, the unaligned allocation of g_World1 causes the access violation (simply put, g_World1's address is not divisible by 16).

Sort of solution: enable structure member alignment by 16 bytes (for MyClass to have the g_World1 "in place"). But still you'll have to ensure, that MyClass instances reside at the addresses divisible by 16.

You can use the placement 'new' operator to allocate MyClass objects.

About alignment see here: How to align pointer




回答3:


Thank you.

Finally I decided to use XMLoadFloat4x4() and XMStoreFloat4x4() functions. I store members of class as Float4x4 and convert them for temporary use to XMMATRIX every render() loop. But... it's a fast or dumb solution?




回答4:


In the Book "Introduction to 3D Game Programming with Directx 11" from "Frank D. Luna" it says:

Do not use XMMATRIX as Member of a class or Structure. Always use XMFloat4x4 and load and store back if you need it.



来源:https://stackoverflow.com/questions/11285680/crash-after-m-xmmatrixidentity-alignment-memory-in-classes

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!