我一直在尝试使用XMVECTOR作为边界框的类成员,因为我做了很多计算,但是每帧只使用一次XMFLOAT3,所以边界框有一个方法可以让我它位于XMFLOAT3的中心,否则它保留在XMVECTOR中;该类与__declspec(align(16))进行了对比,并且在调试模式下工作。但是在Release模式下它崩溃的瞬间我将它设置为:< / p>
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个字节外,我还需要做其他事情吗?
答案 0 :(得分:6)
未在对齐的地址处创建类,因此即使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[]