Я пытался использовать 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 байтов?
Класс не создается по выровненному адресу, поэтому, несмотря на то, что члены 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[]
Других решений пока нет …