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

Started by
9 comments, last by Zahlman 16 years, 4 months ago
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? :)
Advertisement
Could you please post some more of your source code?
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.getType() == 1 && Bricks.exists == true)			Graphics::apply_surface(Bricks.GetXPos(), Bricks.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 );}
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.
Ra
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;}
Try: SDL_Flip(SDL_GetVideoSurface()) just as a test.
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?
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;
If I put my 2 cents in and get a penny for my thoughts, where does my other penny go?
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 ;)
I'd recommend reading my article, too - debugging this kind of error is usually very easy when you know how to use your tools.

Richard "Superpig" Fine - saving pigs from untimely fates - Microsoft DirectX MVP 2006/2007/2008/2009
"Shaders are not meant to do everything. Of course you can try to use it for everything, but it's like playing football using cabbage." - MickeyMouse

This topic is closed to new replies.

Advertisement