使用DirectXMath中的XMVECTOR作为类成员只会在释放模式下导致崩溃? [英] Using XMVECTOR from DirectXMath as a class member causes a crash only in Release Mode?

查看:302
本文介绍了使用DirectXMath中的XMVECTOR作为类成员只会在释放模式下导致崩溃?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直试图使用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 (这真的只是包装 _aligned_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作为类成员只会在释放模式下导致崩溃?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆