This question is builds on a previous question from me.
There I had this construct. It uses SDL2:
void init_window(SDL_Window *window)
{
window = SDL_CreateWindow(…);
}
int main(void)
{
SDL_Window *window;
init_window(window);
}
This didn't work. The answer suggested, I used *&window
as a function parameter instead, and it worked great.
I rewrote the *&window
to **window
as the following:
void init_window(SDL_Window **window)
{
*window = SDL_CreateWindow(…);
}
int main(void)
{
SDL_Window *window;
init_window(&window);
}
And it also works. But I still don't understand why the first version doesn't work. I looked up the implementation details of SDL_Window and it's just a normal typedef
of a struct to put it into ordinary namespace. SDL_CreateWindow returns SDL_Surface *
.
To picture my dilemma, I wrote this simple program:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct Person
{
char *name;
int age;
} Person;
Person *person_create(char *name, int age)
{
Person *who = malloc(sizeof(Person));
who->name = strdup(name);
who->age = age;
return who;
}
void person_get_old(Person *who)
{
who->age += 30;
}
int main(void)
{
Person *susan = person_create("Susan", 23);
person_get_old(susan);
printf("%i\n", susan->age);
}
This prints 53
just as expected, without me having to use pointer to pointer semantics. What is the difference between my implementation and that one of SDL2. This is no SDL2 question, as the one that answered my previous question could answer this without any knowledge of SDL2, so there seems to be some implementation detail I missed. Hope somebody can enlighten me.
Here's a simpler example to illustrate:
void foo(int p) //create new copy of int
{
p = 0; //modify copy, original is unchanged
}
void bar(int* p) //create new copy of pointer
{
*p = 0; //modify object pointer is set to
}
In your SDL example, you were trying to do foo
. The goal was to set the pointer to a new value. However, you only copied the pointer and all changes were done to the copy.
In your Person
example, you were doing bar
. You had an object that was being pointed to, and you wanted to modify it. The correct way to do that is pass it by pointer (or reference).
Since you have an object you want to modify, you need to pass it by pointer (or reference). Since that object is a pointer itself, it will be a pointer to pointer.