【发布时间】:2014-03-16 13:34:44
【问题描述】:
我正在 DirectX11 上编写一个测试应用程序,我有 2 个类 "Box" 和 "camera" 。 “盒子”是要在屏幕上绘制的立方体,这是“相机”:
class camera
{
public :
const camera operator=(const camera& fv) const
{
return fv;
}
XMVECTOR eye;
XMVECTOR at;
XMVECTOR up;
XMVECTOR right;
XMVECTOR left;
XMVECTOR down;
float pitch; //x
float roll; //z
float yaw; //y
XMMATRIX View;
XMMATRIX Projection;
camera();
camera(XMVECTOR eye, XMVECTOR at, XMVECTOR up, float movingOffset, float radius);
void Move(XMVECTOR Offset);
void MoveCameraRight(float offset);
void Rotate(XMVECTOR offset);
void MoveCameraLeft(float offset);
void MoveCameraUp(float offset);
void MoveCameraDown(float offset);
void MoveCameraCloser(float offset);
} ;
我在 Visual Studio 2012 中工作,一切都很完美,直到我决定在 Release 配置下构建我的解决方案。相机构造函数一直落在“未处理的异常:访问违规读取位置...”上在0x0附近的不同地址上。我知道它为什么会发生,我检查了我使用过的所有指针,但我完全不明白发生了什么。这是带有 WinMain 函数的文件的开头:
#include <stdio.h>
#include "DIMouse.h"
#include <string>
#include <sstream>
#include <iostream>
HINSTANCE g_hInst = nullptr;
HWND g_hWnd = nullptr;
HRESULT hr = S_OK;
D3D_DRIVER_TYPE g_driverType = D3D_DRIVER_TYPE_NULL;
D3D_FEATURE_LEVEL g_featureLevel = D3D_FEATURE_LEVEL_11_0;
ID3D11Device* g_pd3dDevice = nullptr;
ID3D11DeviceContext* g_pImmediateContext = nullptr;
IDXGISwapChain* g_pSwapChain = nullptr;
ID3D11RenderTargetView* g_pRenderTargetView = nullptr;
ID3D11VertexShader* g_pVertexShader = nullptr;
ID3D11PixelShader* g_pPixelShader = nullptr;
ID3D11InputLayout* g_pVertexLayout = nullptr;
ID3D11Buffer* g_pVertexBuffer = nullptr;
ID3D11Buffer* g_pConstantBuffer = nullptr;
ID3D11Buffer* g_pIndexBuffer = nullptr;
XMMATRIX g_World; // World matrix
XMMATRIX g_View; // View matrix
XMMATRIX g_Projection; // Projection matrix
int BOXES_COUNT = 50;
int Radius = 20;
FILE* fpsLog = NULL;
Box** boxes;
camera* cam;
FPS fps;
int calculationId = 0;
HRESULT InitWindow( HINSTANCE hInstance, int nCmdShow );
HRESULT InitDevice();
HRESULT InitGeometry();
void parseArgs(LPWSTR lpl);
void CleanupDevice();
LRESULT CALLBACK WndProc( HWND, UINT, WPARAM, LPARAM );
void Render();
HRESULT InitCamera();
void InitCubes(int boxesCount);
cDIObject DIObject;
cMouse Mouse;
int WINAPI wWinMain( _In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPWSTR lpCmdLine, _In_ int nCmdShow )
{
//parse args
parseArgs( lpCmdLine );
UNREFERENCED_PARAMETER( hPrevInstance );
UNREFERENCED_PARAMETER( lpCmdLine );
....
if (FAILED ( InitCamera()))
{
.....
InitCamera() - 一个函数,我在其中调用构造函数,当所有崩溃时:
HRESULT InitCamera()
{
RECT rc;
GetClientRect( g_hWnd, &rc );
UINT width = rc.right - rc.left;
UINT height = rc.bottom - rc.top;
g_World = XMMatrixIdentity();
XMVECTOR Eye = XMVectorSet( 0.0f, 0.0f, -45, 0.0f );
XMVECTOR At = XMVectorSet( 0.0f, 0.0f, 0.0f, 0.0f );
XMVECTOR Up = XMVectorSet( 0.0f, 1.0f, 0.0f, 0.0f );
g_View = XMMatrixLookAtLH( Eye, At, Up );
g_Projection = XMMatrixPerspectiveFovLH( XM_PIDIV4, width / (FLOAT)height, 0.01f, 100.0f );
cam = (camera*)malloc(sizeof(camera));
camera * c = new camera( Eye, At, Up, 0.5, Radius );
cam = c;
cam是camera类的全局指针,别这么看我,这在VS下工作了一段时间。
如果我需要解析取自 lpCmdLine 的命令行参数,我需要分配内存,我认为原因是在 ..Main 开头的内存分配。我使用了 malloc() 和数组(使用 new 然后 delete ),但即使我调用了 free() 并使用了 delete 运算符,也发生了“访问冲突”。但是,现在注意!有时它在 Visual Studio 下工作,当我没有尝试分配内存时,当我刚刚启动一个 .exe 文件时没有工作。然后我决定检查没有内存分配会发生什么,它在 VS 和外部(当我启动 .exe 时)下工作。但是当我从代码中删除所有内存分配以查看会发生什么时,我也得到了“访问冲突...”这一行
camera * c = new camera( Eye, At, Up, 0.5, Radius );
我在调试模式下有工作解决方案,我决定在发布下禁用优化,它在 VS 下工作,而不是在我启动 .exe 时工作。我已经尝试了所有方法,但我不知道如何处理这种情况。我再次检查了,我没有错误的指针。我读过一些关于内存泄漏的文章,但即使我在使用后尝试 delete 或 free() 内存,它还是会崩溃。我很绝望。
【问题讨论】:
-
几乎可以肯定是因为
XMMATRIX成员变量不是 16 字节对齐的。 -
我在项目属性中有16字节结构成员对齐...
标签: visual-studio-2012 memory-management memory-leaks directx directx-11