OK, quindi attualmente sto lavorando a un gioco e ho riscontrato un problema di memoria dopo aver rifatto il codice oggi.C++, perché ricevo violazioni di accesso dopo aver modificato gli oggetti appena assegnati?
Utilizza un progetto basato sui componenti e stavo modificando il modo in cui i componenti sono stati assegnati e distribuiti alle entità. Originariamente alcuni componenti venivano allocati come variabili membro all'interno delle entità, ma ora voglio averli allocati altrove e passati all'entità tramite puntatore.
È possibile vedere come ho implementato questo di seguito con un codice di esempio dal mio progetto. In sostanza, faccio scorrere tutte le entità e allocare i componenti per loro. Il problema è che sto colpendo una violazione di accesso alla prima riga di "avvio" di "instanceObject" sulla sesta iterazione e non ho idea del perché. Usando il debugger, non sembra che nessuna delle variabili punti ad un indirizzo non valido.
Ecco cosa sto facendo per creare entità e componenti.
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
}
E qui è il codice pertinente dal componente.
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;
}
Qualche idea di cosa potrebbe causare questo comportamento e come dovrei risolverlo?
C'è una cosa che non è nel codice che potrebbe sicuramente causare problemi, il costruttore di XMLoadFloat3 (o è una funzione?) Che accetta un XMFLOAT3 * (non memorizza quel puntatore, vero?) –
La copia costruttore di 'InstanceObject' è proprio come quello che verrebbe generato gratuitamente dal compilatore. Potresti semplicemente cancellarlo e avresti lo stesso comportamento. –
Non vedo perché lo farebbe. Carica una serie di 3 float in un XMVECTOR che è un tipo di dati speciale che utilizza un registro SIMD o qualcosa del genere. (http://msdn.microsoft.com/en-us/library/windows/desktop/microsoft.directx_sdk.loading.xmloadfloat3%28v=vs.85%29.aspx) – KlashnikovKid