Lewis
Lewis

Reputation: 1350

In SDL, does SDL_Quit() free every surface?

Basically, on surfaces that are going to exist right until the program terminates, do I need to run SDL_FreeSurface() for each of them, or would SDL_Quit() take care of all this for me?

I ask mainly because the pointers to a number of my surfaces are class members, and therefore I would need to keep track of each class instance (in a global array or something) if I wanted to run SDL_FreeSurface() on each of their respective surfaces. If SDL_Quit() will do it all in one fell swoop for me, I'd much rather go with that :D

Upvotes: 5

Views: 5583

Answers (3)

William Breathitt Gray
William Breathitt Gray

Reputation: 11976

I checked out the SDL 1.2.15 source code to see what actually happens when SDL_Quit is called. Gemini14's answer is correct: SDL_Quit will only free the main SDL_Surface returned by SDL_SetVideoMode.

Here's why:

  1. SDLQuit calls SDLQuitSubSystem to quit every subsystem
  2. SDLQuitSubSystem will call several subsystem quit functions
    • In particular, SDL_VideoQuit is called.
  3. SDL_VideoQuit first checks if the static global pointer current_video is not NULL.
    • If current_video is not NULL, the function precedes to clean up several global variables.
    • SDL_FreeSurface is called on SDL_ShadowSurface or SDL_VideoSurface
      • SDL_ShadowSurface or SDL_VideoSurface is initialized and returned from SDL_SetVideoMode

Since SDL_FreeSurface is only called on the main SDL_Surface initialized by SDL_SetVideoMode, we can reason that all other SDL_Surface variables allocated memory are not freed with a call to SDL_Quit, and must therefore be freed with explicit calls to SDL_FreeSurface.

However, since generally for all programs the operating system will free the memory automatically when the program ends, freeing the SDL_Surface variables is only a concern if your program continues after SDL_Quit.

Upvotes: 4

Tatsh
Tatsh

Reputation: 3690

It is best practise to clear all your surfaces that you know you are using with SDL_FreeSurface().

Similarly, if you create an array of pointers that all call malloc and therefore take up heap space, exiting the program will not clear up all the used space on every system.

int **memspots[1024];
for (i = 0; i < 1024; i++) {
  memspots[i] = malloc(1 * sizeof(int *)); // 1024 pointers to ints stored in heap memory
}

At the end of your application, you would definitely want to call free in a similar fashion.

for (i = 0; i < 1024; i++) {
  free(memspots[i]);
}

It is only best practise to free any memory used any time you can whenever possible, whether at run time and of course at exit.

My GL texture function for SDL temporarily uses an SDL_Surface to gather some image data (taken from SDL_image) and has this at the end:

  if (surface != NULL) // Will be NULL if everything failed and SOMEHOW managed to get here
    SDL_FreeSurface();

  return;

Upvotes: 1

Gemini14
Gemini14

Reputation: 6254

It's been a while since I used SDL, but I'm pretty sure SDL_Quit just cleans up the screen surface (the main screen buffer that you set up at the beginning). You have to free the other surfaces you create manually or you get leaks. Of course, since they're already class members, one way to do that easily would be to just free them up in the class destructor.

Upvotes: 3

Related Questions