Sign in to follow this  
Sean_Seanston

SDL: "Unhandled exception ... Access violation" when I make my 5th SDL_Surface* ???

Recommended Posts

Ok, I'm making a clone of Breakout ATM. It was actually going very well up to now and I have no idea what's wrong. Basically, I've created all my bricks and blitted their graphic to the screen. I have 4 different colours of bricks I plan to randomly assign. Right now, I can get them all to display perfectly using my surface for the yellow brick image. However, once I define another SDL_Surface*, I get "Unhandled exception at 0x6812992b in Breakout.exe: 0xC0000005: Access violation reading location 0x00000004.". This surface is declared in the exact same way as the 4 other surfaces and I haven't even loaded an image onto it or done anything apart from declare it. The surfaces are declared as "static SDL_Surface*" in my Graphics class. When I try to run the program and it gives me the exception, it highlights this area of code:
void Graphics::update()
{
	SDL_Flip( Graphics::screen );
}
This function is used to update the screen, as you can see. "screen" is another of the "SDL_Surface*"s in the program. I've looked around about this kind of error but I haven't been able to get any closer to why it's happening. It seems very strange that there would be no problem with the first 4 surfaces and only declaring another causes the program to break... Any ideas, please? :)

Share this post


Link to post
Share on other sites
Ok, here is "graphics.h"...

#ifndef GRAPHICS_H
#define GRAPHICS_H

#include "SDL/SDL.h"
#include "SDL/SDL_image.h"
#include <string>
#include "paddle.h"
#include "brick.h"

class Graphics
{
public:
static const int SCREEN_WIDTH = 640;
static const int SCREEN_HEIGHT = 480;
static const int SCREEN_BPP = 32;

static SDL_Surface* background;
static SDL_Surface* paddle;
static SDL_Surface* screen;
static SDL_Surface* brick_y;
static SDL_Surface* brick_b;

static void init();
static void loadImages();
static void render();
static void update();
static void cleanUp();

static SDL_Surface* load_image( std::string filename );
static void apply_surface( int x, int y, SDL_Surface* source, SDL_Surface* destination );
};

#endif




and this is "graphics.cpp"...

#include "graphics.h"

SDL_Surface* Graphics::background;
SDL_Surface* Graphics::paddle;
SDL_Surface* Graphics::screen;
SDL_Surface* Graphics::brick_y;
SDL_Surface* Graphics::brick_b; <--- ****This bit of code causes the exception****

SDL_Surface* Graphics::load_image( std::string filename )
{
SDL_Surface* loadedImage = NULL;

SDL_Surface* optimizedImage = NULL;

loadedImage = IMG_Load( filename.c_str() );

if( loadedImage != NULL)
{
optimizedImage = SDL_DisplayFormat( loadedImage );

SDL_FreeSurface( loadedImage );
}

return optimizedImage;
}

void Graphics::init()
{
SDL_Init( SDL_INIT_EVERYTHING );

Graphics::screen = SDL_SetVideoMode( Graphics::SCREEN_WIDTH, Graphics::SCREEN_HEIGHT, Graphics::SCREEN_BPP, SDL_SWSURFACE );

SDL_WM_SetCaption( "B-B-B-BREAKOUT!!!!", NULL );

Brick::setBricks();
}

void Graphics::loadImages()
{
Graphics::background = Graphics::load_image("bg.jpg");
Graphics::paddle = Graphics::load_image("paddle.jpg");
Graphics::brick_y = Graphics::load_image("brick_y.jpg");
}

void Graphics::render()
{
Graphics::apply_surface(0, 0, Graphics::background, Graphics::screen);
Graphics::apply_surface(paddle1.GetXPos(), paddle1.GetYPos(), Graphics::paddle, Graphics::screen);

for(int i = 0; i < NUM_BRICKS; i++)
{
if(Bricks[i].getType() == 1 && Bricks[i].exists == true)
Graphics::apply_surface(Bricks[i].GetXPos(), Bricks[i].GetYPos(), Graphics::brick_y, Graphics::screen);
}
}

void Graphics::update()
{
SDL_Flip( Graphics::screen );
}

void Graphics::cleanUp()
{
SDL_FreeSurface( Graphics::background );

SDL_Quit();
}

void Graphics::apply_surface( int x, int y, SDL_Surface* source, SDL_Surface* destination )
{
SDL_Rect offset;

offset.x = x;
offset.y = y;

SDL_BlitSurface( source, NULL, destination, &offset );
}


Share this post


Link to post
Share on other sites
It looks like Graphics::screen is null. The access violation at 0x00000004 would seem to be SDL_Flip trying to access some member of Graphics::screen (at offset 4).

Solution: Check the return value of SDL_SetVideoMode in Graphics::init(). It's probably null.

Share this post


Link to post
Share on other sites
Hmm... that doesn't seem to be the problem. I put this in the main loop:

	if(SDL_SetVideoMode( Graphics::SCREEN_WIDTH, Graphics::SCREEN_HEIGHT, Graphics::SCREEN_BPP, SDL_SWSURFACE ) == NULL)
quit = true;


And it doesn't quit, so it must not be returning NULL.

Any other ideas? Here's main.cpp if it helps:

#include "main.h"

bool quit = false;

int main(int argc, char* args[])
{
srand(SDL_GetTicks());

Graphics::init();

Graphics::loadImages();

while(quit == false)
{
fps.start();

while( SDL_PollEvent( &Logic::event ) )
{
Logic::handleInput();

if( Logic::event.type == SDL_QUIT )
{
quit = true;
}
}

//LOGIC
Logic::moveSprites();

//RENDERING
Graphics::render();

Graphics::update();

if(fps.get_ticks() < 1000 / FRAMES_PER_SECOND)
{
SDL_Delay( ( 1000 / FRAMES_PER_SECOND ) - fps.get_ticks() );
}
}

Graphics::cleanUp();

return 0;
}

Share this post


Link to post
Share on other sites
Cool... I replaced

SDL_Flip( Graphics::screen );


with

SDL_Flip( SDL_GetVideoSurface() );


and now it's working perfectly ^_^

Thanks a lot :p

But why was it causing an exception in the first place? I suppose I should use SDL_GetVideoSurface() all the time instead of a specific surface, right?

Share this post


Link to post
Share on other sites
I'd say Ra's got the answer -- screen seems to be a NULL value. Since all those other surfaces are declared the same way, you might run into similar errors soon when you start using them...

Have you tried setting each of the pointers in the .cpp file to NULL? You're supposed to initialize static variables.

Graphics.cpp

SDL_Surface* Graphics::background = NULL;
SDL_Surface* Graphics::paddle = NULL;
SDL_Surface* Graphics::screen = NULL;
SDL_Surface* Graphics::brick_y = NULL;
SDL_Surface* Graphics::brick_b = NULL;

Share this post


Link to post
Share on other sites
Hmm... strange. I got it to work with SDL_GetVideoSurface(), then somehow it stopped working even though I'm fairly sure I got it back to when it worked...

Now anyway, I put Graphics::screen back in instead of SDL_GetVideoSurface() and initialized all the pointers to NULL and it works. If I remove the initializations to NULL, I get an exception. So that's what was wrong.

Thanks for your help, I suppose I know now why initializing variables is always good practice ;)

Share this post


Link to post
Share on other sites

Graphics::background = Graphics::load_image("bg.jpg");
Graphics::paddle = Graphics::load_image("paddle.jpg");
Graphics::brick_y = Graphics::load_image("brick_y.jpg");

Graphics::screen = SDL_SetVideoMode( Graphics::SCREEN_WIDTH, Graphics::SCREEN_HEIGHT, Graphics::SCREEN_BPP, SDL_SWSURFACE );


And where, exactly, were you planning to set Graphics::brick_b? :)

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this