Search code examples
c++runtime-errordirect3d10

weird access violation error


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


Solution

  • 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.