Использование XMVECTOR из DirectXMath в качестве члена класса вызывает сбой только в режиме выпуска?

Я пытался использовать XMVECTOR в качестве члена класса для ограничивающего прямоугольника, так как я делаю много вычислений, но я использую XMFLOAT3 только один раз на кадр, поэтому ограничивающий прямоугольник имеет метод, который дает мне его центр в XMFLOAT3 в противном случае он остается в XMVECTOR; класс обнуляется с __declspec (align (16)) и работает в режиме отладки. Однако в режиме Release происходит сбой, как только я его что-то установил:

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

Всякий раз, когда я делаю:

Box A;

Box B;

A = B;

Это дает сбой, давая мне 0xC0000005: Место чтения нарушения доступа 0x00000000.
Также он падает, когда я создаю его как указатель:

Box* A = new Box();

Это конструктор:

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

Опять же, это нормально работает в режиме отладки, но в версии Release происходит сбой. Что может изменить режим Release, что приведет к созданию недействительного кода? Нужно ли делать что-то еще, кроме выравнивания блока по 16 байтов?

2

Решение

Класс не создается по выровненному адресу, поэтому, несмотря на то, что члены XM * выровнены по 16-байтовым границам, выравнивание родительского элемента неправильно выравнивает их, вызывая сбой.

Для предотвращения этого вам нужно использовать _mm_alloc (который на самом деле просто оборачивает _aligned_alloc), или замените распределитель по умолчанию на тот, который возвращает блоки, минимально выровненные до 16 байтов (в x64 это случай с распределителем по умолчанию).

простое решение этого в C ++ состоит в создании базового класса для всех классов, содержащих члены XM *, который выглядит следующим образом:

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>
{
//...
};

Как отмечает @Dave, это минимальный пример, который вы бы хотели перегрузить. все new а также delete операторы, в частности new[] а также delete[]

6

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]