Search code examples
cpointerssdl

SDL2 confusion with pointers c


I'm trying to program a basic game with SDL2 library and I am getting a little bit confused with a basic concept.

Basically I would like to make a function:

void quit_clean (SDL_Window *window, SDL_Renderer *renderer)
{
 if (renderer != NULL)
        SDL_DestroyRenderer(renderer);
 if (window != NULL)
        SDL_DestroyWindow(window);

 exit(EXIT_FAILURE);
}

I would call this function each time there is an error so I can free the renderer and the window properly before to quit the program e.g.

texture = SDL_CreateTextureFromSurface(renderer, tmp);
if(texture==NULL){
      printf ("SDL_CreateTextureFromSurface Error: : %s\n", SDL_GetError());
      quit_clean (&window, &renderer);
}

Where I am getting confused is if I need to call this function from another function how does it work ?

To be precise I would have:

  1. My main() function where I create my *window and my *renderer
  2. a new my_function() called from main() in which I would among other stuffs create a texture from a surface and test errors
  3. and finally my quit_clean() function called from my_function() in case of error.

The way I see it, in order to pass my window and my renderer from main() to quit_clean() using my_function() the prototypes would be then:

void my_function (SDL_Window **window, SDL_Renderer **renderer);
void quit_clean (SDL_Window ***window, SDL_Renderer ***renderer);

Am I correct or not? If yes then how could I call this function from main() if needed.

If I call "quit_clean (&window, &renderer);" from my main() the types are not correct anymore then.

Or maybe I could create pointers from window and renderer and pass those pointers to quit_clean(). I don't know I'm confused, I'm not sure if my thought process is correct.

Do you have any tips for this kind of situation?


Solution

  • You don't need the double pointer as arguments to your functions:

    int my_function (SDL_Window *window, SDL_Renderer *renderer);
    int quit_clean (SDL_Window *window, SDL_Renderer *renderer);
    

    As you might have noticed, i've added a return type (int), because every function should return a result, indicating success or failure.

    Secondly, it would be better not to call the quit_clean function from other functions, instead, if you encounter an error in for e.g. my_function, return an error and call the quit_clean function in the main function.

    Like this:

    int main() 
    {
        SDL_Window *window = NULL; 
        SDL_Renderer *renderer = NULL;
    
        window = SDL_CreateWindow(...); 
    
        if (window) {
    
            renderer = SDL_CreateRenderer(window, ...);
    
            if (renderer) {
    
                int err = my_function(window, renderer);
    
                if (!err) { //success: 0, error: -1
                    //do what is needed to be done
                }
    
            }
    
        }
    
        //finally clean up, 
        //no matter the case (either due to error or program termination)
        quit_clean(window, renderer);
    
        return 0;
    }
    

    In the quit_clean function you have to check the passed arguments (although i think that SDL checks them too, but better than sorry):

    int quit_clean (SDL_Window *window, SDL_Renderer *renderer)
    {
        //other cleanup first
    
        //finally
        if (renderer != NULL)
            SDL_DestroyRenderer(renderer);
        if (window != NULL)
            SDL_DestroyWindow(window);
        SDL_Quit();
    }
    

    And for clarity an example of my_function:

    int my_function (SDL_Window *window, SDL_Renderer *renderer)
    {
        if (some_condition_does_not_hold)
            return -1;
    
        //do your stuff
        //never call quit_clean if something goes wrong, return either -1 or
        //some other (previously defined) negative error number
    
        //finally
        return 0; //success
    }