Reputation: 3755
I am working with C and I'm a bit rusty. I am aware that *
has three uses:
However, what does it mean when there are two asterisks (**
) before a variable declaration:
char **aPointer = ...
Thanks,
Scott
Upvotes: 67
Views: 64257
Reputation: 163228
It declares a pointer to a char
pointer.
The usage of such a pointer would be to do such things like:
void setCharPointerToX(char ** character) {
*character = "x"; //using the dereference operator (*) to get the value that character points to (in this case a char pointer
}
char *y;
setCharPointerToX(&y); //using the address-of (&) operator here
printf("%s", y); //x
Here's another example:
char *original = "awesomeness";
char **pointer_to_original = &original;
(*pointer_to_original) = "is awesome";
printf("%s", original); //is awesome
Use of **
with arrays:
char** array = malloc(sizeof(*array) * 2); //2 elements
(*array) = "Hey"; //equivalent to array[0]
*(array + 1) = "There"; //array[1]
printf("%s", array[1]); //outputs There
The []
operator on arrays does essentially pointer arithmetic on the front pointer, so, the way array[1]
would be evaluated is as follows:
array[1] == *(array + 1);
This is one of the reasons why array indices start from 0
, because:
array[0] == *(array + 0) == *(array);
Upvotes: 57
Reputation: 123448
It declares aPointer
as a pointer to a pointer to char.
Declarations in C are centered around the types of expressions; the common name for it is "declaration mimics use". As a simple example, suppose we have a pointer to int named p
and we want to access the integer value it's currently pointing to. We would dereference the pointer with the unary *
operator, like so:
x = *p;
The type of the expression *p
is int
, so the declaration of the pointer variable p
is
int *p;
In this case, aPointer
is a pointer to a pointer to char; if we want to get to the character value it's currently pointing to, we would have to dereference it twice:
c = **aPointer;
So, going by the logic above, the declaration of the pointer variable aPointer
is
char **aPointer;
because the type of the expression **aPointer
is char
.
Why would you ever have a pointer to a pointer? It shows up in several contexts:
strtol
library function, whose prototype (as of C99) is
long strtol(const char * restrict str, char ** restrict ptr, int base);
The second argument is a pointer to a pointer to char; when you call strtol
, you pass the address of a pointer to char as the second argument, and after the call it will point to the first character in the string that wasn't converted.
void foo(char **arr)
{
size_t i = 0;
for (i = 0; arr[i] != NULL; i++)
printf("%s\n", arr[i]);
}
void bar(void)
{
char *ptrs[N] = {"foo", "bar", "bletch", NULL};
foo(ptrs); // ptrs decays from char *[N] to char **
}
#define ROWS ...
#define COLS ...
...
char **arr = malloc(sizeof *arr * ROWS);
if (arr)
{
size_t i;
for (i = 0; i < ROWS; i++)
{
arr[i] = malloc(sizeof *arr[i] * COLS);
if (arr[i])
{
size_t j;
for (j = 0; j < COLS; j++)
{
arr[i][j] = ...;
}
}
}
}
Upvotes: 11
Reputation: 3002
C and C++ allows the use of pointers that point to pointers (say that five times fast). Take a look at the following code:
char a;
char *b;
char **c;
a = 'Z';
b = &a; // read as "address of a"
c = &b; // read as "address of b"
The variable a
holds a character. The variable b
points to a location in memory that contains a character. The variable c
points to a location in memory that contains a pointer that points to a location in memory that contains a character.
Suppose that the variable a
stores its data at address 1000 (BEWARE: example memory locations are totally made up). Suppose that the variable b
stores its data at address 2000, and that the variable c
stores its data at address 3000. Given all of this, we have the following memory layout:
MEMORY LOCATION 1000 (variable a): 'Z'
MEMORY LOCATION 2000 (variable b): 1000 <--- points to memory location 1000
MEMORY LOCATION 3000 (variable c): 2000 <--- points to memory location 2000
Upvotes: 52
Reputation: 45104
It means that aPointer
points to a char pointer.
So
aPointer: pointer to char pointer
*aPointer :pointer to char
**aPointer: char
An example of its usage is creating a dynamic array of c strings
char **aPointer = (char**) malloc(num_strings);
aPointer gives you a char, which can be used to represent a zero-terminated string.
*aPointer = (char*)malloc( string_len + 1); //aPointer[0]
*(aPointer + 1) = (char*)malloc( string_len + 1); //aPointer[1]
Upvotes: 6