Вопрос

I've been trying to use XMVECTOR as a class member for a bounding box, since I do a lot of calculations, but I use the XMFLOAT3 only once per frame, so the bounding box has a method that gives me it's center in a XMFLOAT3, otherwise it stays in a XMVECTOR;The class is delcared with __declspec(align(16)) and works in debug mode.However in Release mode it crashes the instant I set it to something:

    Box& Box::operator=(const Box& box)
    {
        _center = box._center;
        _extents = box._extents;
        return *this;
    }

Whenever I do:

Box A;

Box B;

A = B;

It crashes, giving me 0xC0000005: Access violation reading location 0x00000000. Also it crashes when I create it as a pointer:

Box* A = new Box();

This is the constructor:

    Box::Box()
    {
        center = XMVectorZero();
        extents = XMVectorSplatOne();
    }

Again, this works fine in Debug mode, but in Release it crashes.What could Release mode be changing that would generate invalid code?Do I need to do something else, other than aligning the box to 16 bytes?

Это было полезно?

Решение

The class is not being created at an aligned address, so even though the XM* members are aligned on 16-byte boundaries, the parent's alignment miss-aligns them, causing the crash.

To prevent this you need to use _mm_alloc (which really just wraps _aligned_alloc), or replace the default allocator with one that returns blocks minimally aligned to 16 bytes (under x64 this the case with the default allocator).

a simple solution to this in C++ is to create a base class for all classes the contain XM* members that looks like the following:

template<size_t Alignment> class AlignedAllocationPolicy
{
    public:
    static void* operator new(size_t size)
    {
        return _aligned_malloc(size,Alienment);
    }

    static void operator delete(void* memory)
    {
        _aligned_free(memory);
    }
};

class MyAlignedObject : public AlignedAllocationPolicy<16>
{
//...
};

As pointed out by @Dave, this is a minimal example, you'd want to overload all the new and delete operators, specifically new[] and delete[]

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top