Handmade Hero » Forums » Code » C - triple pointers help
nyeecola
Italo
13 posts
#12878 C - triple pointers help
1 month, 1 week ago Edited by Italo on Aug. 16, 2017, 5:53 a.m.

1
2
3
4
5
void initGfx(SDL_Surface ***textures, SDL_Surface ***sprites, SDL_Surface *screen){
    (*sprites)[0] = loadSprite("gfx/blastoise.png", screen);
    //This line crashes the program for accessing invalid memory (SEG_FAULT)
    //More stuff...
}


1
2
3
SDL_Surface *spriteText[1] = {5};

initGfx(&textures, &spriteText, screenSurface);


On GDB, if I print (*sprites) when inside the function (right before the line that crashes it) the debugger shows that it is a (SDL_Surface **) with value 0x5, which doesn't make sense since 0x5 should be an element of the array, not the array itself.

Does anyone know why this could be happening?
mmozeiko
Mārtiņš Možeiko
1477 posts
1 project
#12879 C - triple pointers help
1 month, 1 week ago Edited by Mārtiņš Možeiko on Aug. 16, 2017, 5:58 a.m.

Because in C the array variable is not a pointer. So taking address of will not give you pointer to pointer.
It will be equal to itself (array == &array). Array only "decays" to pointer when used in expressions like "array + 3".

This is easier to understand if you think what actual storage looks like.

If you do "int arr[4] = { 0, 1, 2, 3 };" then memory on stack will look like this:
1
2
3
4
5
6
+---+---+---+---+
+ 0 + 1 + 2 + 3 +
+---+---+---+---+
^
|
+-- "arr" variable starts here


So if in your code write "int* ptr = &arr;" where ptr will point to? Obviously to location where memory of "arr" starts, right? But it is exactly same location:
1
2
3
4
5
6
+---+---+---+---+
+ 0 + 1 + 2 + 3 +
+---+---+---+---+
^
|
+-- "ptr" points to here

If you try to display value of "arr" and "&arr" you'll see that they have exactly same value (address).

To work around this issue create temporary pointer:
1
2
SDL_Surface** spriteTextArray = spriteText;
initGfx(&spriteTextArray, &spriteText, screenSurface);


But why do you need to pass address of array to this function? Cann't it simply accept "SDL_Surface **textures" ? Triple pointer here would mean that function wants to change whole array itself:
1
2
3
SDL_Surface** sprites;
initGfx(&sprites, ...); // initGfx modifies sprites array
use(sprites[0]); // now we can use it

Do you really need address of array here?