Sign in to follow this  
ars140

SDL_FreeSurface Crashes

Recommended Posts

I am trying to make a game, and below is the code for the loop to aim (most of it, haven't put some of the finer, but unnecessary for now, pieces of code in). I want to have an object (called "object") follow the mouse (and it works and everything), and I want it to have the loop free the previous object and blit the new one, and free the previous one and blit the new one, etc. (to make it appear to follow the mouse), but SDL_FreeSurface makes the loop crash. When I comment it out, everything works perfectly (albeit the object just fills the screen where the mouse is, as the previous iterations are never freed). I think it has something to do with memory allocation, but my knowledge of memory allocation and how to deal with memory allocation is sketchy at best. Does anyone know how to solve this problem? Thank you very much in advance.

Here is the code:

Notes: The if statements with the location conditions are there so you can only aim at a certain area of the screen. Also, the "down" variable is in there so that it can moderate the mouse clicking (without it, the sdl_mousemotion would occur without first clicking). And I have tried putting SDL_Delays into the code between flipping the screen and freeing the object, they don't have any ill effect on the loop. It's all the SDL_FreeSurface, as far as I can tell.

for (;;)

{ while ( SDL_PollEvent(&event1) )
{ switch (event1.type)
{ case SDL_MOUSEBUTTONDOWN:
if (event1.button.button == SDL_BUTTON_LEFT)
{
down=0;
i = event1.button.x;
j = event1.button.y;

if ((i>=246 && i<=522) && (j>=743 && j<=999))
{
down=1;
apply_surface(i,j,object,screen);
SDL_Flip(screen);
//SDL_FreeSurface(object);
}
}
break;
case SDL_MOUSEMOTION:
if (down==1)
{
i = event1.motion.x;
j = event1.motion.y;

if ((i>=246 && i<=522) && (j>=743 && j<=999))
{
apply_surface(i,j,object,screen);
SDL_Flip(screen);
//SDL_FreeSurface(object);
}
else
{
down=0;
break;
}
}
break;
case SDL_MOUSEBUTTONUP:
if (event1.button.button == SDL_BUTTON_LEFT)
{
if (down==1)
{
i = event1.button.x;
j = event1.button.y;
apply_surface(i,j,object,screen);
SDL_Flip(screen);
//SDL_FreeSurface(object);
down=0;
}
}
break;
case SDL_QUIT:
exit(0);
}
}
}

Share this post


Link to post
Share on other sites
Your event loop executes multiple times. If you free the surface, you might call SDL_BlitSurface() later on with an invalid pointer. If you are freeing a surface that might be used again, you should NULL the pointer and test for NULL before using it.

However, it sounds like you misunderstand SDL_Surfaces and how they interact with SDL_BlitSurface() and SDL_FreeSurface(). A SDL_Surface can be though of as an image in memory. It is not a sprite, that is it does not remember its position or where it was blitted. SDL_BlitSurface() copies the image data from a source surface to a destination surface. Finally, SDL_FreeSurface() is used to dispose of the memory for an image when it is no longer needed.

To make a surface follow the mouse on the screen, the simplest solution is to clear the screen (e.g. use SDL_FillRect() with a black colour) and draw the surface in the current mouse location. A harder solution is to maintain a second surface for each "sprite". So when you go to blit the mouse, first blit the area the mouse will be drawn on onto a hidden back buffer and then draw the mouse on the screen. When you move the mouse, restore the screen using the back buffer, then repeat the first step to draw the mouse in the new location. I would go with the former option if at all possible.

Finally avoid drawing during the input loop. Instead, process all the input first and then draw the mouse in the new location and flip the screen.

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