0

我收到了一个(对我来说)奇怪的运行时访问冲突错误。我有一个类 GUI,它包含指向另一个类 Crosshair 的实例的原始指针。但是,当我尝试访问该指针时,会出现运行时错误!我说的是访问指针,我什至不必取消引用它来获取错误。

这是错误:

Unhandled exception at 0x00d4c486 in GPEngine.exe: 0xC0000005: Access violation reading location 0x00000004.

错误返回到这一行:在下面提供int a = (int)m_pCrosshair;GUI::Draw()方法中。


编辑:

我发现了问题。它发生在我向你们隐藏的代码中,同时试图隐藏尽可能多的不相关代码......问题是这样的:

bool PsychoBots_Game::InitGame()
{
//more code...
return true;
//////GUI
    GUIOnIntialisationInfo GUIdesc;
    GUIdesc.pContentManager = m_pContentManager;
    GUIdesc.pDevice = m_pLevel->GetDevice();

    m_pGUI = new GUI(GUIdesc);
}

换句话说,纯粹的愚蠢……对不起!我没有编写该方法的第一部分,所以我不知道返回值,因为我在初始化自己的东西时从不使用它......


老的:

代码:

十字准线.h

#pragma once

#include "D3DUtil.h"

class ContentManager;
class RenderContext;

class Crosshair
{
public:
    Crosshair(ID3D10Device* pDevice, ContentManager *pContentManager);
    virtual ~Crosshair();

    void Draw(ID3D10Device* pDevice, int clientWidth, int clientHeight);

private:
    ID3D10InputLayout*          m_pVertexLayout;
    ID3D10Buffer*               m_pVertexBuffer;

    ID3D10Effect*               m_pDefaultEffect;
    ID3D10EffectTechnique*      m_pDefaultTechnique;

    ID3D10EffectMatrixVariable* m_pWVPVariable;
    ID3D10EffectShaderResourceVariable* m_pDiffuseMapVariabele;

    ID3D10ShaderResourceView *  m_pTextureRV;

private:
    //disabled
    Crosshair(const Crosshair& b);
    Crosshair& operator= (const Crosshair& b);
};

十字准线.cpp

#include "stdafx.h"

#include "Crosshair.h"

#include "ContentManager.h"
#include "RenderContext.h"

#include "vertex.h"

Crosshair::Crosshair(ID3D10Device* pDevice, ContentManager *pContentManager)
    :m_pVertexLayout(nullptr)
    ,m_pVertexBuffer(nullptr)
    ,m_pDefaultEffect(nullptr)
    ,m_pDefaultTechnique(nullptr)
    ,m_pWVPVariable(nullptr)
    ,m_pDiffuseMapVariabele(nullptr)
    ,m_pTextureRV(nullptr)
{
//////Load Texture
    m_pTextureRV = pContentManager->GetTexture(pDevice, _T("GUI/Crosshair.png"));

//////Load Effect & Technique
    m_pDefaultEffect = pContentManager->GetEffect(pDevice,  _T("Effect/Texture2D.fx"));

    //get  technique 
    m_pDefaultTechnique = m_pDefaultEffect->GetTechniqueByIndex(0);
    if(!m_pDefaultTechnique->IsValid())
    {
        MessageBox(0,_T("Technique not valid"),_T("ERROR"),0);
        exit(-1);
    }

//////Get Effect Variables
    m_pDiffuseMapVariabele = m_pDefaultEffect->GetVariableBySemantic("DiffuseMap")->AsShaderResource();
    if(!m_pDiffuseMapVariabele->IsValid()) {
        MessageBox(0,_T("Getting EffectVariable m_pDiffuseMapVariabele Failed"),_T("ERROR"),0);
        exit(-1);
    }

    m_pWVPVariable = m_pDefaultEffect->GetVariableBySemantic("WVP")->AsMatrix();
    if(!m_pWVPVariable->IsValid()) {
        MessageBox(0,_T("Getting EffectVariable m_pWVPVariable Failed"),_T("ERROR"),0);
        exit(-1);
    }

//////Define InputLayout
    D3D10_INPUT_ELEMENT_DESC layout[] =
    {
        { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D10_INPUT_PER_VERTEX_DATA, 0 },
        { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 12, D3D10_INPUT_PER_VERTEX_DATA, 0 }
    };
    UINT numElements = sizeof(layout)/sizeof(layout[0]);

    // Create the input layout
    D3D10_PASS_DESC PassDesc;
    // Get the pass decriptor from the effect technique
    m_pDefaultTechnique->GetPassByIndex( 0 )->GetDesc( &PassDesc );
    HR(pDevice->CreateInputLayout( layout, numElements, PassDesc.pIAInputSignature, PassDesc.IAInputSignatureSize, &m_pVertexLayout ));

//////Build Vertexbuffer
    VertexPosTex v[4];

    v[0].pos = D3DXVECTOR3(-0.5f, -0.5f, 0.0f); v[0].tex.x = 0.0f; v[0].tex.y = 1.0f;
    v[1].pos = D3DXVECTOR3(-0.5f,  0.5f, 0.0f); v[1].tex.x = 0.0f; v[1].tex.y = 0.0f;
    v[2].pos = D3DXVECTOR3( 0.5f, -0.5f, 0.0f); v[2].tex.x = 1.0f; v[2].tex.y = 1.0f;
    v[3].pos = D3DXVECTOR3( 0.5f,  0.5f, 0.0f); v[3].tex.x = 1.0f; v[3].tex.y = 0.0f;

    //fill a buffer description to copy the vertexdata into graphics memory
    D3D10_BUFFER_DESC bd = {};
    bd.Usage = D3D10_USAGE_DEFAULT;
    bd.ByteWidth = sizeof( VertexPosTex ) * sizeof(v);
    bd.BindFlags = D3D10_BIND_VERTEX_BUFFER;
    bd.CPUAccessFlags = 0;
    bd.MiscFlags = 0;

    D3D10_SUBRESOURCE_DATA initData;
    initData.pSysMem = v;
    //create a ID3D10Buffer in graphics memory containing the vertex info
    HR(pDevice->CreateBuffer( &bd, &initData, &m_pVertexBuffer ));
}

Crosshair::~Crosshair()
{
    m_pVertexLayout->Release();
    m_pVertexBuffer->Release();
}

void Crosshair::Draw(ID3D10Device* pDevice, int clientWidth, int clientHeight)
{
//////Set the input layout
    pDevice->IASetInputLayout( m_pVertexLayout );

//more code...
}

图形用户界面.h

#pragma once

#include "D3DUtil.h"

#include "GUIOnInitialisationInfo.h"
#include "GUIPerFrameInfo.h"
#include "GUIPerTickInfo.h"

#include "Crosshair.h"

class GUI
{
public:
    virtual ~GUI();
    GUI(const GUIOnIntialisationInfo& info);

    void Tick(const GUIPerTickInfo& info);
    void Draw(const GUIPerFrameInfo& info);

private:
    Crosshair* m_pCrosshair;
};

图形用户界面.cpp

#include "stdafx.h"
#include "GUI.h"
GUI::GUI(const GUIOnIntialisationInfo& info)
    :m_pCrosshair(new Crosshair(info.pDevice, info.pContentManager))
{
}
GUI::~GUI()
{
    delete m_pCrosshair;
}
void GUI::Tick(const GUIPerTickInfo& info)
{
}
void GUI::Draw(const GUIPerFrameInfo& info)
{
    int a = (int)m_pCrosshair; 
    m_pCrosshair->Draw(info.pDevice, info.clientWidth, info.clientHeight);
}

错误返回到这一行:int a = (int)m_pCrosshair;

当我删除这一行时:它将中断 m_pCrosshair->Draw(info.pDevice, info.clientWidth,info.clientHeight);

有错误: Unhandled exception at 0x001fc49a in GPEngine.exe: 0xC0000005: Access violation reading location 0x00000004


以下是在我的应用程序中实例化 GUI 实例的方式:

class PsychoBots_Game : public D3DApp
{
//more code...
private:
    GUI* m_pGUI;
//more code...
};

(请不要问我为什么有一个 InitGame() 方法,我们必须这样做才能让我们的老师开心 [lol])

bool PsychoBots_Game::InitGame()
{
//////GUI
    GUIOnIntialisationInfo GUIdesc;
    GUIdesc.pContentManager = m_pContentManager;
    GUIdesc.pDevice = m_pLevel->GetDevice();

    m_pGUI = new GUI(GUIdesc);
}

最后,WinMain:

int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE prevInstance,
                   TCHAR* cmdLine, int showCmd)
{
    PsychoBots_Game *pGameApp= new PsychoBots_Game(hInstance);

    if(pGameApp->InitApp())pGameApp->Run();
    delete pGameApp;
}

谁能告诉我是什么导致了这个问题?如果您仍然需要更多代码,请在评论中询问:)

谢谢

4

3 回答 3

2

您的 bool PsychoBots_Game::InitGame() 不返回值。

您确定在 m_pGUI 上调用了 Draw 方法吗?

你确定 PsychoBots_Game::InitGame() 被调用了吗?从您提供的代码中,仅调用 pGameApp->InitApp() 。m_pGUI 在 InitGame 中初始化。

于 2012-01-02T14:43:00.797 回答
2

您的类中有一个取消引用,但您看不到:m_pCrosshair是一个成员,因此任何访问都将通过this指针,根据错误,该指针似乎为 0。找不到 的调用点GUI::Draw,但是那里的实例指针是 0 或者未初始化。

于 2012-01-02T14:44:56.837 回答
0

类类 GUI 不遵守三规则(同时包含 RAW 指针)。

因此,您可能已经制作了对象的副本并且原始对象被删除,从而留下了一个带有无效指针的对象。

有一个简单的方法可以检查这是否是问题:如果 GUI 私有,则将复制构造函数和赋值运算符设为私有,如果出现编译时错误,那么这就是你的问题。

作为旁注,您的代码包含许多原始指针的方式。
你应该看看什么是真正需要的指针,什么可以是普通的对象。在必须有指针的地方,然后看看使用智能指针。

于 2012-01-02T14:48:23.057 回答