2

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?

ulak blade
  • 2,515
  • 5
  • 37
  • 81
  • Note that you don't need to create a ``Box`` class. [DirectXMath](http://blogs.msdn.com/b/chuckw/archive/2012/03/27/introducing-directxmath.aspx) includes ``BoundingBox`` already in the ``DirectXCollision.h`` header. – Chuck Walbourn Aug 05 '15 at 04:21

1 Answers1

6

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[]

Necrolis
  • 25,836
  • 3
  • 63
  • 101
  • so I wouldn't need declspec align anymore?Shouldn't they be doing the same thing?Or is _mm_alloc specialized for classes with __m128 members? – ulak blade Apr 01 '13 at 23:24
  • @DEIMOS: taken from the MSDN page for `__declspec(align())`: `Note that normal allocators, such as malloc, C++ operator new, and the Win32 allocators return memory that will most likely not be sufficiently aligned for __declspec(align(#)) structures or arrays of structures.` As such, it'll only affect allocations the compiler has control over, such as stack and stack variables, as well as struct/class offset alignment. `_mm_malloc` & `_aligned_malloc` return correctly allocated data, with `_mm_malloc` being a macro shorthand for SSE types. – Necrolis Apr 01 '13 at 23:30
  • 2
    see also Type Usage Guidelines at http://msdn.microsoft.com/en-us/library/windows/desktop/ee418725(v=vs.85).aspx for another discussion of this topic for xmmath. – Yostage Jun 13 '13 at 21:02
  • You also likely need the array operators [] to make this correct. I know I wound up needing them; also, if you're using DXUT keep in mind if you're using their GUI it will do allocations of arrays in YOUR code (from the headers) using your allocator and then free them in its own code; thus you must put all 4 operators in the DXUT.h for this to interop properly. – Dave Jul 24 '15 at 17:25
  • 1
    If you are new to DirectXMath, you should consider using the [SimpleMath](https://github.com/Microsoft/DirectXTK/wiki/SimpleMath) wrapper in [DirectX Tool Kit](https://github.com/Microsoft/DirectXTK) which transparently handles the alignment issues for you. – Chuck Walbourn Aug 05 '15 at 04:20