Pointers to pointers show up in a number of situations. Probably the most common is when you need a function to write to a pointer argument.
Consider the following:
void foo( T *p ) // for any type T
{
*p = new_value(); // write to the thing p points to
}
void bar( void )
{
T var;
foo( &var ); // foo updates value of var
...
}
Here the function foo
is updating the variable var
defined in bar
through the pointer p
.
Now let's replace type T
with the pointer type Q *
:
void foo( Q **p )
{
*p = new_pointer_value(); // write to the thing p points to
}
void bar( void )
{
Q *var;
foo( &var ); // foo updates the value of var
...
}
The semantics are exactly the same; we're writing a new value to var
. The only difference is that var
has a pointer type, so we need to use multiple levels of indirection in foo
.
A second common situation is when you have an array of pointers, and you pass that array to another function. For example:
void foo( char **s )
{
while ( *s )
puts( *s++ );
}
void bar( void )
{
char *strings[] = { "blurga", "bletch", "blah", NULL };
foo( strings );
}
strings
is an array of pointers to char
; each element of the array is the address of a string literal (or NULL). In the call to foo
the array expression strings
is converted ("decays") to an expression of type "pointer to pointer to char
", and the value of the expression is the address of the first element of the strings
array1. Since the first element of the array is a pointer, then the address of the first element is a pointer to a pointer.
The third case is when you're allocating memory for a 2D array by pieces:
T **arr = malloc( sizeof *arr * rows );
if ( arr )
{
for( size_t i = 0; i < rows; i++ )
{
arr[i] = malloc( sizeof *arr[i] * cols );
}
}
1. Except when it is the operand of the sizeof
or unary &
operators, or is a string literal being used to initialize another array in a declaration, an expression of type "N-element array of T
" will be converted ("decay") to an expression of type "pointer to T
", and the value of the expression will be the address of the first element of the array.