Được rồi, vì vậy tôi hiện đang làm việc trên một trò chơi và gặp sự cố về bộ nhớ sau khi tái cấu trúc một số mã ngay hôm nay.C++, tại sao tôi nhận được vi phạm quyền truy cập sau khi sửa đổi các đối tượng mới được phân bổ?
Nó sử dụng thiết kế dựa trên thành phần và tôi đã sửa đổi cách các thành phần được phân bổ và truyền cho các thực thể. Ban đầu một số thành phần được phân bổ như các biến thành viên trong các thực thể nhưng bây giờ tôi muốn chúng được phân bổ ở nơi khác và được truyền cho thực thể thông qua con trỏ.
Bạn có thể xem cách triển khai thực hiện điều này bên dưới bằng mã mẫu từ dự án của tôi. Tôi chủ yếu lặp qua tất cả các thực thể và phân bổ các thành phần cho chúng. Vấn đề là tôi đánh một vi phạm truy cập ở dòng đầu tiên của "bắt đầu" các "instanceObject" trên lặp thứ 6 và không có ý tưởng tại sao. Sử dụng trình gỡ lỗi, nó không giống như bất kỳ biến nào trỏ đến một địa chỉ không hợp lệ.
Đây là những gì tôi đang làm để tạo các thực thể và thành phần.
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
}
Và đây là mã liên quan từ thành phần.
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;
}
Bất kỳ ý tưởng nào về nguyên nhân gây ra hành vi này và cách khắc phục sự cố?
Có một thứ không có trong mã có thể gây ra vấn đề, hàm tạo XMLoadFloat3 (hoặc nó là hàm?) Lấy XMFLOAT3 * (nó không lưu con trỏ đó, phải không?) –
Bản sao constructor của 'InstanceObject' giống như hàm tạo bởi trình biên dịch. Bạn chỉ có thể xóa nó và bạn sẽ có được hành vi tương tự. –
Tôi không hiểu tại sao nó lại xảy ra. Nó tải một mảng của 3 nổi vào một XMVECTOR đó là một kiểu dữ liệu đặc biệt mà sử dụng một đăng ký SIMD hoặc một cái gì đó. (http://msdn.microsoft.com/en-us/library/windows/desktop/microsoft.directx_sdk.loading.xmloadfloat3%28v=vs.85%29.aspx) – KlashnikovKid