-1

im trying to make a simple pong game for school coursework and im getting stuck following the tutorials i have.

When i run my code i get this error "Unhandled exception at 0x00042DE0 in assignment 2.exe: 0xC0000005: Access violation writing location 0x00000000."

it happens when calling a function in a class my code is as follows (let me know if i miss something important)

Jack C
  • 3
  • 2
  • 1
    Did you try stepping through the code, while inspecting the values of the variables, with the debugger? – Algirdas Preidžius Jan 09 '17 at 21:57
  • 1
    "C++ error i dont know how to solve" is quite a common problem around here. Recommend a more descriptive title. – user4581301 Jan 09 '17 at 21:58
  • 1
    "Access violation writing location 0x00000000." when accessing the first member of an object suggests `this` is a NULL pointer. Can't say more, or suggest a solution, without a [mcve] – user4581301 Jan 09 '17 at 22:03
  • Seems that you go beyond the size of array `m_ScreenBuffer` –  Jan 09 '17 at 22:09
  • added in more of the code. and i will go try the debugger now – Jack C Jan 09 '17 at 22:12
  • Better, Jack, but we also need to also see the context in which `SetPixel` is invoked. – user4581301 Jan 09 '17 at 22:14
  • @JackCharlesworth you're first step whenever you get this kind of error is to use the debugger. It will show you exactly where the error occurs. This might not be the location of the problem. But it will certainly help you look. And it will help avoid down votes on stackoverflow. – Matt Jan 09 '17 at 22:15
  • Based on the limited information available and the access to a null pointer, I'd guess that CHAR_INFO is a typedef to a pointer (right click, got to definition) which you are using as a straight struct. – Mike Jan 09 '17 at 22:27
  • i have gone through the decoder and the x and y integers stay the same, attributes becomes 64. also added my entire code in. – Jack C Jan 09 '17 at 22:27

2 Answers2

0

In

BouncingBall::BouncingBall()
{
Initialise(0, 0, 0, 0, 0);
m_pRenderer = NULL;
}

m_pRenderer is explicitly NULLed. It is allocated no storage.

However this looks like it should be corrected in

void BouncingBall::Initialise(int m_PositionX, int m_PositionY, int m_DirectionX, int m_DirectionY, ASCIIRenderer* m_pRenderer){


}

But BouncingBall::Initialise has not been fully implemented and discards the provided renderer. m_pRenderer is still NULL.

Later in

void BouncingBall::Render() 
{
if (m_pRenderer == NULL){
    CHAR_INFO ball;
    ball.Char.AsciiChar = 0;
    ball.Attributes = BACKGROUND_RED;
    m_pRenderer->SetPixel(m_PositionX, m_PositionY, ball);
    }
}

m_pRenderer is tested to ensure that it still points at nothing and is then invoked. This is the reverse of the logic OP needs, and SetPixel is called on a NULL pointer. Boom.

Solution: Fully implement BouncingBall::Initialise and replace the test in BouncingBall::Render for is NULL if (m_pRenderer == NULL) with is NOT NULL if (m_pRenderer != NULL)

Though a better approach is to embrace RAII and not have an initialize function in the first place. Do it in the constructor. Test for a valid renderer in the constructor and throw an exception to abort construction if invalid.

This way there is always a valid renderer if there is an object and if not NULL checks are unnecessary.

Edit:

Fully implemented BouncingBall::Initialise

void BouncingBall::Initialise(int PositionX, 
                              int PositionY, 
                              int DirectionX, 
                              int DirectionY, 
                              ASCIIRenderer* pRenderer){
    m_PositionX = PositionX;
    m_PositionY = PositionY;
    m_DirectionX = DirectionX;
    m_DirectionY = DirectionY;
    m_pRenderer = pRenderer;
}

Note the names of the parameters are changed to not match the member variables.

But...

RAII (Resource acquisition is initialization) suggests that you not use a BouncingBall::Initialise function and instead take advantage of constructors

void BouncingBall::BouncingBall(int PositionX, 
                                int PositionY, 
                                int DirectionX, 
                                int DirectionY, 
                                ASCIIRenderer* pRenderer) : // Member Initializer List
    m_pRenderer(pRenderer),
    m_PositionX(PositionX),
    m_PositionY(PositionY),
    m_DirectionX(DirectionX),
    m_DirectionY(DirectionY)
{
    if (m_pRenderer == NULL)
    {
        // throw exception here. This will prevent having an improperly 
        // initialized BouncingBall acting as a ticking timebomb.
        // the constructed object will be politely destroyed as if it never existed
    }
}

Documentation on Member initializer list.

Community
  • 1
  • 1
user4581301
  • 33,082
  • 7
  • 33
  • 54
  • thank you very much! but sorry if its dumb, how do i fully implemenet bouncingBall::Initialise?? – Jack C Jan 09 '17 at 22:45
  • @JackC The variables in `void BouncingBall::Initialise(int m_PositionX, int m_PositionY, ...)` are not the same as those defined as class members (`int m_PositionX; int m_PositionY; ...`) even though they have the same name. They are different, temporary variables with identical names. You must assign these temporary variables to the member variables to make them stay around. Because they have the same names, you cannot simply `m_PositionX = m_PositionX;` because this looks like a self assignment. Any good programming text will tell you how to get around this or avoid it outright. – user4581301 Jan 09 '17 at 22:53
  • thank you so much any chance you can show me where to read these texts :) – Jack C Jan 09 '17 at 22:58
  • @JackC Library works. If you can afford to drop $40, a copy of Programming: Principles and Practice Using C++ is a great start. Writer invented the language and is also an effective teacher rather than the average mega brain who can't explain smurf. If your budget is tighter, [you can get a heavily abridged (and more difficult) version here.](https://isocpp.org/tour) Stack Overflow also maintains [The Definitive C++ Book Guide and List](http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list) for other places to get wisdom. – user4581301 Jan 09 '17 at 23:08
  • thanks a lot ill check it out, is it simple to do to fix what ive done? – Jack C Jan 09 '17 at 23:14
  • @JackC Updated. The rest and details is best covered in a book. – user4581301 Jan 09 '17 at 23:29
0

In my experience, there have been two causes for this error:

1) You tried to call a function with a pointer that was invalid.

2) You tried to enter data into the buffer that would've placed the pixel outside of the screen.