1

I am learning to create C++ applications using SDL2 library and I encountered a problem while trying to organise my code.

Here's a simple example ilustrating the situation:

void createWindow (SDL_Window *gameWindow)
{
    gameWindow = SDL_CreateWindow(/* arguments here */);
}

int main (int argc, char* argv[])
{
    SDL_Window* gameWindow = NULL;
    createWindow(gameWindow);
    // some code here...
}

Why doesn't it work? When I try to compile the code, SDL_GetError() screams: "Invalid Renderer".

When I make it that way

SDL_Window* createWindow (SDL_Window* gameWindow)
{ 
    gameWindow = SDL_CreateWindow (/* arguments here*/);
    return gameWindow;
}

it works. But I don't like it that way.

I may not understand something about pointers or the way SDL2 works on them, but I thought passing one to the function lets me operate directly on the variables intead of copies, so I don't have to return anything. For me it looks like I was operating on the copy of the variable adress, but not the variable itself.

Vovulus
  • 13
  • 3
  • 3
    What about: `SDL_Window* createWindow () { return SDL_CreateWindow (/* arguments here*/); }` –  Jan 28 '16 at 11:20
  • You're changing `createWindow`'s copy of the pointer. – Michael Jan 28 '16 at 11:20
  • Even if you don't like it, most people would prefer simply returning the pointer here. Note that the SDL function does just that too. – Emil Laine Jan 28 '16 at 11:51

4 Answers4

5

Arguments in C are passed by value, that is, arguments are copied and every modification applied to arguments in a function alters the value of that copy, not the actually passed argument.

Resolve the problem by

  • passing a reference to a pointer:

    void createWindow (SDL_Window*& gameWindow)
    {
        gameWindow = SDL_CreateWindow(/* arguments here */);
    }
    
  • passing a pointer to a pointer. Watch out: this is C-ish and bad C++ code!

    void createWindow (SDL_Window** gameWindow)
    {
        *gameWindow = SDL_CreateWindow(/* arguments here */);
    }
    
  • returning the pointer:

    SDL_Window* createWindow()
    {
        return SDL_CreateWindow(/* arguments here */);
    }
    
cadaniluk
  • 15,027
  • 2
  • 39
  • 67
  • 1
    I'll advise to use the "returning pointer version" this is clearer. The others versions are confusing. – Mickael Jan 28 '16 at 12:00
1

When you pass your pointer it gets passed by value! So you are just changing the adress of the local copy in your function

Solution:

void createWindow(SDL_Window **gameWindow)
{
     *game_Window = SDL_CreateWindow(/*...*/);
}

int main()
{
      SDL_Window* gameWindow = NULL;
      createWindow(&gameWindow);
}

this way you give the adress of your pointer to the function and enable it to change the value of it!

0

You are passing a pointer, but you are trying to assign the pointer itself. Try passing by reference, like so:

void createWindow (SDL_Window *& gameWindow)

Hope this helps. The rest of the code should not be altered for this to work.

Vicente Cunha
  • 205
  • 1
  • 7
-1

It's not about how SDL works, but how c++ handles paramemters.

When you pass any variable as a parameter to a function, the default behavior is to take the value of the variable and copy to the variable inside the function. So.. in your case when you do.

createWindow( gameWindow ); What is going on under the hood is just passing NULL as parameter. If you want to modify the gameWindow pointer, you have to pass it's address.

for example:

void createWindow( SDL_Window ** pointer ) { 
    *pointer = SDL_CreateWindow( /** args **/ );
}

And call it: createWindow( &gameWindow );

You can see a deep explanation about that on that question: What's the difference between passing by reference vs. passing by value?

Community
  • 1
  • 1
Rafael Fontes
  • 1,195
  • 11
  • 19
  • 1
    Do not use pointers to pointers in C++. Use references or return the value. – cadaniluk Jan 28 '16 at 11:26
  • Can you point me to something explaining why pointer to pointer is a bad thing? – Rafael Fontes Jan 28 '16 at 11:28
  • [Here](http://programmers.stackexchange.com/questions/56935/why-are-pointers-not-recommended-when-coding-with-c) and [here](http://programmers.stackexchange.com/questions/163393/whats-so-bad-about-pointers-in-c). Pointers to pointers specifically because they are even easier to get wrong and references and the C++ standard library do a much better, safer, and more beautiful job. Also, it's not only about passing variables but expressions in general. – cadaniluk Jan 28 '16 at 11:32
  • More generally, you should (almost) _never_ accept a pointer argument if null pointer is not an acceptable value. – Emil Laine Jan 28 '16 at 11:48