странная ошибка нарушения доступа - PullRequest
0 голосов
/ 02 января 2012

Я получаю (для меня) странную ошибку нарушения доступа во время выполнения. У меня есть класс, GUI, который содержит необработанный указатель на экземпляр другого класса, Crosshair. Однако, когда я пытаюсь получить доступ к этому указателю, я получаю ошибку во время выполнения! Я говорю о доступе к указателю, мне даже не нужно разыменовывать его, чтобы получить ошибку.

Вот ошибка:

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

Ошибка возвращается к этой строке: int a = (int)m_pCrosshair; Который находится в методе GUI::Draw(), представленном ниже.


EDIT:

Я нашел проблему. Это произошло в коде, который я скрывал от вас, ребята, пытаясь скрыть как можно больше ненужного кода ... Проблема была в следующем:

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;

Когда я удаляю эту строку: она сломается в 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 (), мы должны сделать это, чтобы наши учителя были счастливы [смеется])

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

Может кто-нибудь сказать мне, что является причиной проблемы? Если по какой-либо причине вам все еще нужно больше кода, просто спросите в комментарии:)

Спасибо

Ответы [ 3 ]

2 голосов
/ 02 января 2012

В вашем классе есть разыменование, но вы его не видите: m_pCrosshair является членом, поэтому любой доступ будет проходить через указатель this, который в случае ошибки равен 0Я не могу найти сайт вызова GUI::Draw, но указатель экземпляра там равен 0 или не инициализирован.

2 голосов
/ 02 января 2012

Ваш bool PsychoBots_Game :: InitGame () не возвращает значение.

Вы уверены, что метод Draw вызывается в m_pGUI?

Вы уверены, что вызывается PsychoBots_Game :: InitGame ()? Из предоставленного вами кода вызывается только pGameApp-> InitApp (). m_pGUI инициализируется в InitGame.

0 голосов
/ 02 января 2012

Графический интерфейс класса класса не подчиняется правилу трех (хотя и содержит указатель RAW).

Таким образом, вы, вероятно, сделали копию объекта, а исходный объект был удален, в результате чего у вас остался объектс недопустимым указателем.

Существует простой способ проверить, является ли это проблемой : сделать конструктор копирования и оператор присваивания, если GUI закрытым, если вы получаете ошибку времени компиляции, тогда этоВаша проблема.

В качестве примечания, ваш код содержит множество указателей RAW.
Вам следует взглянуть, что действительно должно быть указателем, а что может быть обычным объектом.В местах, где у вас должны быть указатели, смотрите на умные указатели.

...