C ++,为什么我收到访问冲突修改新分配的对象后?

好了,所以我目前工作的一个游戏,今天重构一些代码后,撞上了内存问题。

它采用基于组件的设计,我是如何修改的组件被分配和传递给实体。 原来一些部件被分配为实体内部成员变量,但现在我想有他们在其他地方分配,并通过指针传递给实体。

你可以看到我是如何实现低于此示例代码从我的项目。 我基本上是通过所有的实体迭代并分配组件他们。 问题是我打一个访问冲突在6日迭代“启动”中的“instanceObject”的第一线,不知道为什么。 使用调试器,它并不像任何变量指向一个无效地址。

下面是我在做什么来创建的实体和组件。

for (unsigned int i = 0; i < 512; ++i) { InstanceObject* _pInstanceObject = new InstanceObject; // Initialize temporary variables XMFLOAT3 _position, _rotation; float _angle = (i / 512.0f) * (2.0f * XM_PI), _scale = (float)pResourceManager->numberGenerator.GetInt(50, 5); _position.x = 100000.0f * cos(_angle) + pResourceManager->numberGenerator.GetInt(50000, -25000); _position.y =(float) pResourceManager->numberGenerator.GetInt(50000, -25000); _position.z = 100000.0f * sin(_angle) + pResourceManager->numberGenerator.GetInt(50000, -25000); _rotation.x = (XM_PI * 2) * (pResourceManager->numberGenerator.GetInt(100, 0) / 100.0f); _rotation.y = (XM_PI * 2) * (pResourceManager->numberGenerator.GetInt(100, 0) / 100.0f); _rotation.z = (XM_PI * 2) * (pResourceManager->numberGenerator.GetInt(100, 0) / 100.0f); // Set component's state using the temporary variables. _pInstanceObject->StartUp(&_position, &_rotation, &XMFLOAT3(_scale, _scale, _scale), &XMFLOAT3(0.0f, 0.0f, 1.0f), &XMFLOAT3(1.0f, 0.0f, 0.0f), &XMFLOAT3(0.0f, 1.0f, 0.0f) ); // Hand pointer of the component to entity. // Entity will handle deallocating component }

这里是从组件相关的代码。

class InstanceObject { private: XMVECTOR anteriorAxis, lateralAxis, normalAxis, position, rotationQuaternion, scale; XMMATRIX translationMatrix, rotationMatrix, scaleMatrix; void SetAnteriorAxis(const XMFLOAT3 *_anteriorAxis) { anteriorAxis = XMLoadFloat3(_anteriorAxis); } void SetLateralAxis(const XMFLOAT3 *_lateralAxis) { lateralAxis = XMLoadFloat3(_lateralAxis); } void SetNormalAxis(const XMFLOAT3 *_normalAxis) { normalAxis = XMLoadFloat3(_normalAxis); } public: InstanceObject(void) { } InstanceObject(const InstanceObject& _object) : anteriorAxis(_object.anteriorAxis), lateralAxis(_object.lateralAxis), normalAxis(_object.normalAxis), position(_object.position), rotationQuaternion(_object.rotationQuaternion), scale(_object.scale), translationMatrix(_object.translationMatrix), rotationMatrix(_object.rotationMatrix), scaleMatrix(_object.scaleMatrix) {} ~InstanceObject(void) { } bool StartUp(const XMFLOAT3 *_position, const XMFLOAT3 *_rotation, const XMFLOAT3 *_scale, const XMFLOAT3 *_lookAxis, const XMFLOAT3 *_strafeAxis, const XMFLOAT3 *_upAxis); void SetPosition(const XMFLOAT3* _position) { position = XMLoadFloat3(_position); } void SetRotationQuaternion(const XMFLOAT3 *_rotation) { rotationQuaternion = XMQuaternionRotationRollPitchYaw(_rotation->x, _rotation->y, _rotation->z); } void SetScale(const XMFLOAT3 *_scale) { scale = XMLoadFloat3(_scale); } } bool InstanceObject::StartUp(const XMFLOAT3 *_position, const XMFLOAT3 *_rotation, const XMFLOAT3 *_scale, const XMFLOAT3 *_lookAxis, const XMFLOAT3 *_strafeAxis, const XMFLOAT3 *_upAxis) { SetPosition(_position); SetRotationQuaternion(_rotation); SetScale(_scale); SetAnteriorAxis(_lookAxis); SetLateralAxis(_strafeAxis); SetNormalAxis(_upAxis); return true; }

任何想法这可能是导致这种行为,我应该如何解决呢?

--------------解决方案-------------

我认为,问题是,在你的InstanceObject类XMVECTOR需要进行16字节对齐,而新运营商将不能保证这个要求。 您可以添加一个快速检查到你的代码,以确认 - 检查InstanceObject指针&0xF的是在它崩溃迭代非零。

如果是这样的话,你可以写一个保证右对齐和使用新的位置自定义分配器。

这似乎成为会员(这里是在这个问题上的现有连接的bug报告,有几个网页,如果你搜索)使用时,必须与XMVECTOR一个相当普遍的问题。

如果你只是想快速解决,让你与其他的东西,你可以添加一个静态的operator new和delete你的类声明实现类似下面的代码片段:

void* InstanceObject::operator new( size_t size )
{
// _aligned_malloc is a Microsoft specific method (include malloc.h) but its
// straightforward to implement if you want to be portable by over-allocating
// and adjusting the address
void *result = _aligned_malloc( size, 16 );
if( result )
return result;

throw std::bad_alloc();
}

void InstanceObject::operator delete( void* p )
{
if( p ) _aligned_free(p);
}

如果InstanceObject都有一个共同的一生,你可以用自己的对齐舞台分配器更换使用_aligned_malloc的,使delete无操作,提高工作效率。

你采取临时的地址! 这甚至不允许!

// Set component's state using the temporary variables.
_pInstanceObject->StartUp(&_position,
&_rotation,
&XMFLOAT3(_scale, _scale, _scale), // not valid
&XMFLOAT3(0.0f, 0.0f, 1.0f), // not valid
&XMFLOAT3(1.0f, 0.0f, 0.0f), // not valid
&XMFLOAT3(0.0f, 1.0f, 0.0f) // not valid
);

我建议你​​打开了警告级别的编译器设置,并启用尽可能多的符合标准的可能。 事情变得更容易,当你的编译器会告诉你你做错了什么。

作为一个解决方案,您可以尝试简单地按值传递的对象:

_pInstanceObject->StartUp(_position,
_rotation,
XMFLOAT3(_scale, _scale, _scale),
XMFLOAT3(0.0f, 0.0f, 1.0f),
XMFLOAT3(1.0f, 0.0f, 0.0f),
XMFLOAT3(0.0f, 1.0f, 0.0f)
);

bool StartUp(XMFLOAT3 _position, XMFLOAT3 _rotation, XMFLOAT3 _scale,
XMFLOAT3 _lookAxis, XMFLOAT3 _strafeAxis, XMFLOAT3 _upAxis);

它看起来像在栈上被分配的XMFLOAT3结构,而不是在堆上。 他们将得到清理时,他们的变量超出范围。

尝试在堆中分配,而不是你的结构:

XMFLOAT3* _position = new XMFLOAT3;

分类:C# 时间:2015-03-15 人气:1
本文关键词: 内存管理
分享到:

相关文章

Copyright (C) 55228885.com, All Rights Reserved.

55228885 版权所有 京ICP备15002868号

processed in 0.391 (s). 10 q(s)