奇怪的访问冲突错误

发布于 2024-12-24 17:04:35 字数 7062 浏览 2 评论 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);
}

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


旧:

代码:

Crosshair.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);
};

Crosshair.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...
}

GUI.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;
};

GUI.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;

< em>当我删除这一行时:将在 m_pCrosshair->Draw(info.pDevice, info.clientWidth,info.clientHeight);

出现错误: 在 0x001fc49a 处出现未处理的异常在 GPEngine.exe 中:0xC0000005:访问冲突读取位置 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;
}

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

谢谢

I'm getting a (to me) weird run-time access violation error.
I have a class, GUI, that contains a raw pointer to an instance of another class, Crosshair. However, when I try to access that pointer, I get a run-time error! I'm talking about accessing the pointer, I don't even have to dereference it to get the error.

Here's the error:

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

The error returns to this line: int a = (int)m_pCrosshair;
Which is in the GUI::Draw() method, provided below.


EDIT:

I found the problem. It occurred in code I was hiding from you guys, while trying to hide as much irrelevant code as possible... The problem was this:

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);
}

Pure stupidity, in other words... Sorry for this! I did not write the first part of that method so I wasn't aware of the return values since I never use this when initialising my own stuff...


Old:

Code:

Crosshair.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);
};

Crosshair.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...
}

GUI.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;
};

GUI.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);
}

The error returns to this line: int a = (int)m_pCrosshair;

When I delete this line: it will break at m_pCrosshair->Draw(info.pDevice, info.clientWidth,info.clientHeight);

With error: Unhandled exception at 0x001fc49a in GPEngine.exe: 0xC0000005: Access violation reading location 0x00000004


Here is how an instance of GUI is intantiated in my application:

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

(please don't ask me why I have an InitGame() method, we have to do this to make our teachers happy [lol])

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

    m_pGUI = new GUI(GUIdesc);
}

And finally, 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;
}

Can anyone tell me what is causing the problem? If by any chance you still need more code, just ask in a comment :)

Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

叹沉浮 2024-12-31 17:04:35

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

There is a dereference in your class, but one you don't see: m_pCrosshair is a member, so any access will go through the this pointer, which seems to be 0 according to the error. I can't find the invocation site of GUI::Draw, but the instance pointer there is 0 or uninitialized.

黯淡〆 2024-12-31 17:04:35

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

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

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

Your bool PsychoBots_Game::InitGame() does not return value.

Are you sure that Draw method is being called on m_pGUI?

Are your sure PsychoBots_Game::InitGame() is being called ? From the code your provided only pGameApp->InitApp() is called. m_pGUI is initialized in InitGame.

假装不在乎 2024-12-31 17:04:35

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

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

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

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

The class class GUI does not obey the rule of three (while containing a RAW pointer).

Thus you probably have made a copy of the object and the original object got deleted thus leaving you with an object with an invalid pointer.

There is an easy way to check if this is the problem: Make the copy constructor and assignment operator if GUI private if you get a compile time error then this is your problem.

As a side note your code contains way to many RAW pointers.
You should take a look what really needs to be pointers and what can be normal objects. In places where you must have pointers then look at using smart pointers.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文