0xC0000005: Access violation reading location of an Integer? - c++

It seems normally people receive these errors when working with pointers, array, structs, etc. I'm getting it on every integer in a class, which confuses me. I'm sure I'm just missing some small technical detail (I'm a bit new to this).
The exact error is:
First-chance exception at 0x003e6616 in Mine.exe: 0xC0000005:
Access violation reading location 0x00000008.
Unhandled exception at 0x003e6616 in Mine.exe: 0xC0000005:
Access violation reading location 0x00000008.
The code breaks at the first line in this class method:
void Grid::Move(int x, int y)
{
this->offX+=x;
this->offY+=y;
for (int i=0;i<2;i++)
for (int k=0;k<2;k++)
BitmapSetxy(chunks[i][k]->map,this->offX,this->offY);
}
Here is the constructor of Grid:
Grid::Grid()
{
totalW =320*2;
totalH = 320*2;
offX = 0;
offY = 0;
//Fill the chunks array with Maps to be used
for (int i=0;i<2;i++)
for (int k=0;k<2;k++)
chunks[i][k] = new Map(i*320,k*320);
//Everything starts as dirt
for (int x=0;x<(320*2)/20;x++)
for (int y=0;y<(320*2)/20;y++)
blocks[x][y] = bType::Dirt;
}
And the header file:
#ifndef MapDef
#define MapDef
#include "Map.h"
class Grid
{
private:
int totalW, totalH;
int offX, offY;
public:
enum bType
{
Blank,
Dirt,
Copper
};
Map * chunks[2][2];
bType blocks[32][48];
void RemoveBlock(int x, int y);
bType GetBlockAt(int x, int y);
int GetAbsolutePosition20(int);
int GetMapIndex(int);
int GetChunkRelative(int,int);
bType GetBlockBelow(int x, int y);
bType GetBlockAbove(int x, int y);
bType GetBlockSide(int x, int y, bool isRight);
void Move(int x, int y);
Grid();
};
#endif
When looking at the locals view of the current instance of Grid totalW, totalH, offX,offY all show the CXX0030 error, but the two arrays are perfectly fine. What exactly is going on here?
EDIT:
The definition of the grid pointer is stored in a separate little namespace that serves as something of a static class:
namespace Engine
{
static Grid * grid;
static Player * player;
}
It is actually created here in the main cpp file:
//Initialize engine
Engine::grid = new Grid();
Engine::player = new Player(160,240);
Here is the excerpt where it is called, in another class called Player
if (y>392 && y<480 && x>75 && x<152)
{
printf("Right");
Engine::grid->Move(20,0);
}
Edit 2:
I'm sorry, I forgot to remove the "static" keyword from the grid declaration in engine. I believe that was what was causing the problem.

According to the error message, your code is trying to access address 0x00000008, which is very close to 0. This means you probably have a null pointer of type Grid * somewhere and you are calling a function on it.
You should either ensure that the pointer is not null, or check it. For example:
Grid * grid = ...;
if (grid == NULL){ return; }
grid->move(0,1);
Note that NULL is the same as 0.

What is the value of 'this'? Are you trying to dereference a null pointer to an instance of Grid?

Related

C++ object of abstract class type "mazeGenerator" is not allowed: pure virtual function "olcGameEngine::OnUserUpdate" has no overrider

So since im trying to learn c++ i have been followin onelonecoders tutorial, however i am stuck. The class that i made "mazeGenerator" will not be instantiated. other questions like mine have as solution using const on the onUserUpdate function however, this has not worked, I've had other problems that i was able to fix but i cant find a solution for this one.
Thank you very much in advance!
the solution is probably under my nose, but i just cant find it
Heres the code i have written so far:
// mazeGenerater.cpp : This file contains the 'main' function. Program execution begins and ends there.
//
#pragma once
#include <iostream>
#include <stack>
using namespace std;
#include "olcConsoleEngine.h"
class mazeGenerator : public olcConsoleGameEngine {
public:
mazeGenerator(){
m_sAppName = L"MAZE";
}
private:
int m_nMazeWidth;
int m_nMazeHeight;
int *m_maze;
enum{
CELL_PATH_N = 0x01,
CELL_PATH_E = 0x02,
CELL_PATH_S = 0x04,
CELL_PATH_W = 0x08,
CELL_VISITED = 0x10,
};
int m_nVisitedCells;
stack<pair<int , int>> m_stack; // (x, y) coordinate pairs
protected:
virtual bool OnUserCreate() {
//initialize alogrithm
m_nMazeWidth = 40;
m_nMazeHeight = 25;
//allocate maze memory
m_maze = new int[m_nMazeWidth * m_nMazeHeight];
memset(m_maze, 0x00, m_nMazeWidth * m_nMazeHeight);
//push cells to stack
m_stack.push(make_pair(0, 0));
m_maze[0] = CELL_VISITED;
m_nVisitedCells = 1;
return true;
}
virtual bool onUserUpdate(float fElppasedTime) {
// draw stuff
Fill(0, 0, ScreenWidth(), ScreenHeight(), L' ');
for (int x = 0; x < m_nMazeWidth; x++) {
for (int y = 0; y < m_nMazeHeight; y++) {
if (m_maze[y * m_nMazeWidth + x] & CELL_VISITED) {
Draw(x, y, PIXEL_SOLID, FG_WHITE);
}
else {
Draw(x, y, PIXEL_SOLID, FG_BLUE);
}
}
}
return true;
}
};
int main()
{
//create maze and run
mazeGenerator game;
game.ConstructConsole(160, 100, 8, 8);
game.Start();
return 0;
}
// Run program: Ctrl + F5 or Debug > Start Without Debugging menu
// Debug program: F5 or Debug > Start Debugging menu
// Tips for Getting Started:
// 1. Use the Solution Explorer window to add/manage files
// 2. Use the Team Explorer window to connect to source control
// 3. Use the Output window to see build output and other messages
// 4. Use the Error List window to view errors
// 5. Go to Project > Add New Item to create new code files, or Project > Add Existing Item to add existing code files to the project
// 6. In the future, to open this project again, go to File > Open > Project and select the .sln file
Here is lonecoders engine
https://github.com/OneLoneCoder/videos/blob/master/olcConsoleGameEngine.h
i would post the code of the engine itself but I'd end up with more than 30000 characters, sorry!
I think that the problem is that the function you wrote in the derived class, onUserUpdate, should be OnUserUpdate - with a capital O.
In addition, add the override keyword before the function implementation. Change
virtual bool onUserUpdate(float fElppasedTime) {
^^^^^^^
into this
bool onUserUpdate(float fElppasedTime) override {
^^^^^^^^
for all overridden functions - and you will see the errors.

C++ referencing instances created within a function's scope

Context
The context of the problem is that I am currently writing a small library for use with the Arduino in order to act as a game controller. The problem I am encountering has more to do with C++ than anything Arduino specific however.
I've included the libraries' header and source code below, followed by the Arduino code. I've truncated it where possible.
Problem
In short, only the last switch / action I define actually gets properly handles.
These actions get defined in the Arduino setup function. For example:
controller.addSwitchContinuous(10, 0); // Pin 10; btn index 0
means that pin 10 gets mapped to button 0. When pin 10 is switched closed this is treated as the button being pressed. This works fine for a single action but when I start adding more only the last action actually works. So in the following example only pin 9 is recognized:
controller.addSwitchContinuous(10, 0); // <-- Doesn't work
controller.addSwitchContinuous(9, 1); // <-- Works
This goes for any arbitrary number of actions:
controller.addSwitchContinuous(10, 0); // <-- Doesn't work
controller.addSwitchContinuous(9, 1); // <-- Doesn't work
controller.addSwitchContinuous(8, 2); // <-- Doesn't work
controller.addSwitchContinuous(7, 3); // <-- Works
Potential causes
I am fairly novice with C++ so this I suspect I'm doing something wrong with pointers. More specifically, something seems wrong with how the Joystick_ instance gets passed around.
I have been fiddling with the constructor and trying to use references instead of pointers but I couldn't get it to work properly.
I can confirm the iteration in JFSF::loop does iterate over all actions, if I modify it with:
void JFSF::loop()
{
for (int n = 0; n < _nextActionIndex; n++)
{
if (_actions[n])
{
_actions[n]->loop();
_joystick->setButton(n, PRESSED); // Debug: Set button pressed, regardless of switch.
}
}
if (_doSendState)
{
_joystick->sendState();
}
}
then buttons 0 through n get pressed as expected. It is possible that loop() isn't properly being called, but I would expect it to fail for the N = 1 case as well in that case. Furthermore the fact the last action always succeeds would suggest the iteration is ok.
Full code
// JFSF.h
#ifndef JFSF_h
#define JFSF_h
// ... include for Arduino.h and Joystick.h; bunch of defines
namespace JFSF_PRIV
{
class AbstractAction
{
public:
virtual void loop();
};
/* A Switch that essentially acts as a push button. */
class SwitchContinuousAction : public AbstractAction
{
public:
SwitchContinuousAction(Joystick_ *joystick, int pin, int btnIndex);
void loop();
private:
Joystick_ *_joystick;
int _pin;
int _btnIndex;
};
} // namespace JFSF_PRIV
class JFSF
{
public:
JFSF(Joystick_ *joystick, bool doSendState); // doSendState should be true if Joystick_ does not auto send state.
void loop();
void addSwitchContinuous(int inputPin, int btnIndex);
private:
Joystick_ *_joystick;
JFSF_PRIV::AbstractAction *_actions[MAX_ACTIONS];
int _nextActionIndex;
bool _doSendState;
};
#endif
Source file (trimmed):
// JFSF.cpp
#include "Arduino.h"
#include "Joystick.h"
#include "JFSF.h"
#define PRESSED 1
#define RELEASED 0
// Private classes
namespace JFSF_PRIV
{
SwitchContinuousAction::SwitchContinuousAction(Joystick_ *joystick, int pin, int btnIndex)
{
_joystick = joystick;
_pin = pin;
_btnIndex = btnIndex;
pinMode(_pin, INPUT_PULLUP);
}
void SwitchContinuousAction::loop()
{
int _state = digitalRead(_pin) == LOW ? PRESSED : RELEASED;
_joystick->setButton(_btnIndex, _state);
}
} // namespace JFSF_PRIV
JFSF::JFSF(Joystick_ *joystick, bool doSendState)
{
_joystick = joystick;
_nextActionIndex = 0;
_doSendState = doSendState;
}
void JFSF::addSwitchContinuous(int inputPin, int btnIndex)
{
JFSF_PRIV::SwitchContinuousAction newBtnAction(_joystick, inputPin, btnIndex);
_actions[_nextActionIndex++] = &newBtnAction;
}
void JFSF::loop()
{
for (int n = 0; n < _nextActionIndex; n++)
{
if (_actions[n])
{
_actions[n]->loop();
}
}
if (_doSendState)
{
_joystick->sendState();
}
}
For completeness sake, this is the code for the Arduino, but it is pretty much just declarations:
#include <JFSF.h>
// ... A bunch of const declarations used below. These are pretty self explanatory.
// See: https://github.com/MHeironimus/ArduinoJoystickLibrary#joystick-library-api
Joystick_ joystick(HID_REPORT_ID,
JOYSTICK_TYPE_JOYSTICK, // _JOYSTICK, _GAMEPAD or _MULTI_AXIS
BTN_COUNT, HAT_SWITCH_COUNT,
INCLUDE_X_AXIS, INCLUDE_Y_AXIS, INCLUDE_Z_AXIS,
INCLUDE_RX_AXIS, INCLUDE_RY_AXIS, INCLUDE_RZ_AXIS,
INCLUDE_RUDDER, INCLUDE_THROTTLE,
INCLUDE_ACCELERATOR, INCLUDE_BRAKE, INCLUDE_STEERING);
JFSF controller(&joystick, !DO_AUTO_SEND_STATE);
void setup() {
joystick.begin(DO_AUTO_SEND_STATE);
controller.addSwitchContinuous(10, 0); // <-- Doesn't work
controller.addSwitchContinuous(9, 1); // <-- Works
}
void loop() {
controller.loop();
}
References
ArduinoJoystickLibrary (Source for Joystick_) can be found here: https://github.com/MHeironimus/ArduinoJoystickLibrary#joystick-library-api
I dont really understand your code. Please read How to create a Minimal, Complete and Verifiable example. Anyhow, the following is certainly wrong and likely the cause of your problem:
void JFSF::addSwitchContinuous(int inputPin, int btnIndex)
{
JFSF_PRIV::SwitchContinuousAction newBtnAction(_joystick, inputPin, btnIndex);
_actions[_nextActionIndex++] = &newBtnAction;
}
Lets rewrite it a bit for clarity:
void foo(){
T bar;
container[index] = &bar;
}
What happens here is that bar gets destroyed when it goes out of scope, hence the pointer you put into the container, points to garbage. Presumably somewhere else in your code you are dereferencing those pointers, which is undefined behaviour (aka anything can happen).
Long story short: It is a common pattern among c++ beginners to overuse pointers. Most likely you should make container a container of objects rather than pointers and make use of automatic memory managment instead of trying to fight it.
Thanks to #user463035818 and #drescherjm for identifiying the actual problem.
So in the end I fixed it by simply moving the Action object creation up to the Arduino code (where it's essentially global) and passing references to those objects to the controller.
In code this translates to:
JFSF.cpp
void JFSF::addAction(JFSF_PRIV::AbstractAction *action){
_actions[_nextActionIndex++] = action;
}
Arduino code (ino)
// See code in original post
JFSF controller(&joystick, !DO_AUTO_SEND_STATE);
JFSF_PRIV::SwitchContinuousAction btnOne(&joystick, 10, 0);
JFSF_PRIV::SwitchContinuousAction btnTwo(&joystick, 9, 1);
void setup() {
joystick.begin(DO_AUTO_SEND_STATE);
// controller.addSwitchContinuous(10, 0); // Pin 10; btn index 0
// controller.addSwitchContinuous(9, 1); // Pin 9 ; btn index 1
controller.addAction(&btnOne);
controller.addAction(&btnTwo);
}
// loop() is unchanged

Creating an object in device code

I want to create an object on the device and allocate it to a pointer available on the host. Is there something I'm doing wrong in here?
__global__ void createAProduction(DeviceProduction* production) {
production = new AProduction();
}
DeviceProduction * devAProduction = NULL;
cudaMalloc(&devAProduction, sizeof(AProduction));
createAProduction<<<1, 1>>>(devAProduction);
deviceProductions["A"] = devAProduction;
Somewhere further in the code I'd like to do sth. like:
BatchOperation ** devBatchOperations;
cudaMalloc((void **) &devBatchOperations, sizeof(BatchOperation *) * operationCount);
Then I populate that pointer array with that:
void DeviceBatchExecutor::execute(vector<BatchOperation> operationsToPerform) {
BatchOperation ** devBatchOperations;
cudaMalloc((void **) &devBatchOperations, sizeof(BatchOperation *) * operationsToPerform.size());
int i = 0;
for(batchOperationIt it = operationsToPerform.begin(); it != operationsToPerform.end(); ++it) {
BatchOperation * devBatchOperation;
cudaMalloc(&devBatchOperation, sizeof(BatchOperation));
cudaMemcpy(&devBatchOperation, &it, sizeof(BatchOperation), cudaMemcpyHostToDevice);
Vertex * devInputNode = it->inputNode->allocateToDevice();
cudaMemcpy(&(devBatchOperation->inputNode), &devInputNode, sizeof(Vertex *), cudaMemcpyDeviceToDevice);
cudaMemcpy(&(devBatchOperation->production), &(it->production), sizeof(Production *), cudaMemcpyDeviceToDevice);
cudaMemcpy(&devBatchOperations[i], &devBatchOperation, sizeof(BatchOperation *), cudaMemcpyDeviceToDevice);
i++;
}
int operationCount = operationsToPerform.size();
executeOperations<<<operationCount, 1>>>(devBatchOperations);
}
where production is a pointer to the device memory holding that created object AProduction. Then I finally invoke processing via
executeOperations<<<operationCount, 1>>>(devBatchOperations);
So I'm relying on virtual method calls. As those DeviceProduction objects were created on the device, there is also a virtual pointer table so it should work. See example here. But it doesn't since the received batch operations seem random... crashes on invocation.
__global__ void executeOperations(BatchOperation ** operation) {
operation[blockIdx.x]->production->apply(operation[blockIdx.x]->inputNode);
}
Batch operation is a struct holding the production to be executed.
struct BatchOperation {
Production * production;
Vertex * inputNode;
Vertex * outputNode;
};
Is there something I'm doing wrong in here?
Yes, probably. The pointer production is passed to the kernel by value:
createAProduction<<<1, 1>>>(devAProduction);
It points to a location in device memory somewhere, since you've already run cudaMalloc on it. This line of kernel code:
production = new AProduction();
overwrites the pass-by-value copy of the production pointer with a new one, returned by in-kernel new. That is almost certainly not what you had intended. (And you haven't defined what AProduction is.). At the completion of that kernel call, the pass-by-value "copy" of the pointer will be lost anyway. You might be able to fix it like this:
*production = *(new DeviceProduction());
Now your production pointer points to a region in device memory that holds an instantiated (on the device) object, which appears to be your intent there. Creating a new object just to copy it may not be necessary, but that is not the crux of the issue I'm trying to point out here. You can probably also "fix" this issue by passing a pointer-to-pointer to the kernel instead. You would then need to allocate for an array of pointers, and assign one of the individual pointers using the in-kernel new directly, as you have shown.
The remainder of your code has a great many items undefined. For example in the above code it's not clear why you would declare that production is a pointer to a DeviceProduction type, but then try to allocate an AProduction type to it. Presumably that is some form of object inheritance which is unclear.
Since you haven't really provided anything approaching a complete code, I've borrowed some pieces from here to put together a complete worked example, showing object creation/setup in one kernel, followed by another kernel that invokes virtual methods on those objects:
$ cat t1086.cu
#include <stdio.h>
#define N 4
class Polygon {
protected:
int width, height;
public:
__host__ __device__ void set_values (int a, int b)
{ width=a; height=b; }
__host__ __device__ virtual int area ()
{ return 0; }
};
class Rectangle: public Polygon {
public:
__host__ __device__ int area ()
{ return width * height; }
};
class Triangle: public Polygon {
public:
__host__ __device__ int area ()
{ return (width * height / 2); }
};
__global__ void setup_f(Polygon ** d_polys) {
int idx = threadIdx.x+blockDim.x*blockIdx.x;
if (idx < N) {
if (idx%2)
d_polys[idx] = new Rectangle();
else
d_polys[idx] = new Triangle();
d_polys[idx]->set_values(5,12);
}};
__global__ void area_f(Polygon ** d_polys) {
int idx = threadIdx.x+blockDim.x*blockIdx.x;
if (idx < N){
printf("area of object %d = %d\n", idx, d_polys[idx]->area());
}};
int main () {
Polygon **devPolys;
cudaMalloc(&devPolys,N*sizeof(Polygon *));
setup_f<<<1,N>>>(devPolys);
area_f<<<1,N>>>(devPolys);
cudaDeviceSynchronize();
}
$ nvcc -o t1086 t1086.cu
$ cuda-memcheck ./t1086
========= CUDA-MEMCHECK
area of object 0 = 30
area of object 1 = 60
area of object 2 = 30
area of object 3 = 60
========= ERROR SUMMARY: 0 errors
$
Robert's suggestion seems to made it work:
__global__ void createAProduction(DeviceProduction** production) {
int idx = threadIdx.x+blockDim.x*blockIdx.x;
if(idx == 0) {
production[0] = new AProduction();
}
}
Called like this:
DeviceProduction ** devAProduction = NULL;
cudaMalloc(&devAProduction, sizeof(AProduction *));
createAProduction<<<1, 1>>>(devAProduction);
gpuErrchk( cudaPeekAtLastError() );
gpuErrchk( cudaDeviceSynchronize() );
But if I want to keep single pointer structure for deviceProductions array would it be ok to do sth. like this?
deviceProductions["A"] = (DeviceProduction *) malloc(sizeof(AProduction *));
gpuErrchk(cudaMemcpy(deviceProductions["A"], devAProduction, sizeof(AProduction *), cudaMemcpyDeviceToHost));
My intention was to copy the pointer (address) to the host memory from the device memory. Am I doing it right?

Strange errors: EXC_BAD_ACCESS in my class

Here is my code:
typedef struct TItemSelector{
ItemSelectFrame* pItems[2];
} SItemSelector;
class item {
public:
void expMethod();
SItemSelector itemSelector_;
UILayerButton* startBtn_;
};
void item::expMethod(){
startBtn_ = new UILayerButton();
for (i = 0; i < 3; i++) {
itemSelector_.pItems[i] = new ItemSelectFrame();
}
startBtn_->callMethodA();
}
void UILayerButton::callMethodA()
{
this->callMethodB();
}
void UILayerButton::callMethodB()
{
}
On this->callMethodB();, a "EXC_BAD_ACCESS" occoured.
After that I found a work-around:
class item {
public:
void expMethod();
SItemSelector itemSelector_;
SItemSelector itemSelector2_; // work around
UILayerButton* startBtn_;
};
Then everything goes well... I just don't know what happened, but callMethodB() is just an empty method, there's nothing to do with it.
I'm using Apple LLVM 3.1, default setting.
UPDATE: Fixed my code.
In this code:
for (i = 0; i < 3; i++) {
itemSelector_.pItems[i] = new ItemSelectFrame();
}
you are writing over the end of itemSelector_.pItems because pItems is an array of length 2 but you are writing 3 elements.
That then overwrites startBtn_ which happens to appear immediately after itemSelector_ in memory. And that explains the error when you subsequently read the now corrupted startBtn_.
Either change your loop termination test, or increase the length of pItems. I can't tell which one is the correct solution, but clearly you will know.

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