问题描述
我一直试图使用XMVECTOR作为边界框的类成员,因为我做了很多计算,但我每次使用XMFLOAT3只有一次,所以边界框有一个方法,它给我它的中心在XMFLOAT3中,否则它保留在XMVECTOR中;类使用__declspec(align(16))delcared并且在调试模式下工作。然而在发布模式下,它将崩溃的时间我设置为某物:
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();
}
同样,这在Debug模式下可以正常工作,
类不是在对齐的地址创建的,所以即使XM *成员在16字节边界对齐,父对齐错误对齐他们,导致崩溃。
为了防止这种情况,你需要使用 _mm_alloc
(这真的只是包装),或将默认分配器替换为返回最低限度对齐到16个字节的块(在x64下,使用默认分配器的情况下)。
在C ++中一个简单的解决方案是为所有类创建一个基类包含如下所示的XM *成员:
模板< 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所指出的,这是一个最小的例子, > all new
和 delete
运算符,特别是 new [ code>和
delete []
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[]
这篇关于使用DirectXMath中的XMVECTOR作为类成员只会在释放模式下导致崩溃?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!