Reputation: 175
I understand what a pointer is, but I am struggling to understand what they are used for. I could think of situations where you COULD use a pointer, but these situations I can think of, could also be solved in a different way without much more work. Anyway, what I really do not understand, is the use of pointers to pointers. For example I came across this simple C-code:
#include <stdlib.h>
int main(int argc, char** argv)
{
...
}
From what I understood, this is meant to be a program that can be called by the commandline with infinite parameters and is sort of a convention. What exactly is the purpose of char** argv? Why use a pointer to a pointer to a char here? I'm sorry if this is a trivial question, but I seem to really struggle to get the big picture here.
Thank you in advance, Sparkas
Upvotes: 1
Views: 194
Reputation: 123558
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 );
}
}
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.
Upvotes: 1
Reputation: 28921
There are examples of C where argv is alternately declared as an array of pointers:
char *argv[]
The pointer to pointer syntax:
char **argv
declares a pointer to what could be the first pointer in an array of pointers. Another common usage is for passing a pointer to a pointer to a linked list:
node *head; /* pointer to linked list */
/* ... */
/* pass a pointer to head */
list_function(&head);
/* ... */
/* use and update head */
list_function(node **head){ ... }
Upvotes: 1
Reputation: 133609
A pointer to a pointer (to a pointer..) is useful in all the situations in which you need more than one level of indirection.
In the specific circumstance of char** args
you have an array of strings which are the arguments, each string in C is a char*
so basically you have some thing like
char** args
|
-> | char* | char* | char* | char* |
| |
v |
|f|o|o| |
|
v
|b|a|r|
What's strange about this? Think about that T*
defines a type which is a pointer to a T
. Now if T == char*
then you have that char**
defines a pointer to a char*
, which in its turn is a pointer to a char
.
Remember that in C and C++ a pointer can represent an array.
Upvotes: 3