xcrypt
xcrypt

Reputation: 3386

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

Upvotes: 0

Views: 493

Answers (3)

Loki Astari
Loki Astari

Reputation: 264699

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.

Upvotes: 0

thiton
thiton

Reputation: 36059

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.

Upvotes: 2

marcinj
marcinj

Reputation: 50036

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.

Upvotes: 2

Related Questions