Reputation: 195
I have a table structure defined like this:
typedef struct table {
char *key;
void *value;
} Table;
Then I have something like this:
Table **table
as a variable.
What does that mean?
An array of tables?
A table pointer that points to a table pointer?
Upvotes: 1
Views: 412
Reputation: 27934
There are different uses for pointers of pointers. One exemple we use normally is in the declaration of main()
itself:
int main(int argc, char** argv) {
What does this mean?
As you should know, argv
brings you the parameters used with your program when it was run. Each parameter is a string, and as you probably know, a string is also an array of char
.
But argv
is not an array of chars, because argv
does not represent one string alone. argv
is an array of arrays. It can bring you not one string, but many strings.
Each element of argv
is a char*
, an array of char
, one of the many possible parameters.
A representation of argv
could be described as this:
char** argv = {
(char*)"Param 0",
(char*)"Param 1",
(char*)"Param 2",
...
};
Other possible uses for a pointer to a pointer is when you want to assign a value to it as you pass it as parameter to a function.
For instance, the same way you can assign a numeric value to a int
using a pointer like this:
void assign_random_to(int* result) {
*result = rand();
}
int i = 0;
assign_random_to(&i);
// i is now the value of rand()
You can do the same with pointers, and in the same sense as above you will need a pointer to it, a pointer to a pointer:
int try_malloc(void** ptr, int size) {
void* tmp = malloc(size);
if (tmp == NULL)
return 0;
*ptr = tmp;
return 1;
}
char small_buffer[128];
char* buffer = small_buffer;
if (try_malloc(&buffer, 1024))
{
strcpy(buffer, "Big buffer was successfully allocated!");
}
else
{
printf("Failed to alloc a big buffer, original pointer to small buffer preserved.");
}
Answering your comment "Ok, but why not just have ptr be void *ptr instead of void **ptr, and then have ptr = temp?"
Because you cannot simply assign a value to a parameter.
void assign_value_to_parameter(int param) {
param = 2;
// param is now 2, but only in this context
}
int x = 1;
assign_value_to_parameter(x);
// x is still 1, the function did not change its value in this context
The fact the function assign_value_to_parameter()
changed the value of param
doesn't affect the value of the original variable. Thats why you must pass a pointer to something in order to give a function means of changing its value. If the target is already a pointer, you have to pass a pointer to this pointer.
Upvotes: 2
Reputation: 8623
Typically you see a double pointer if you are dynamically allocating an array of pointers. If each struct were individually allocated you would need an array (or other data structure) to hold all the pointers. Creating an array of pointers gives you a pointer to a(n array of) pointer.
Upvotes: 0
Reputation: 477640
When you declare Table **table;
, that makes table
a pointer to a pointer to Table
; for example:
Table x;
Table * p = &x;
Table ** table = &p; // points to p
Table * arr[10]; // array of table pointers
table = arr; // point to first element of arr
Upvotes: 2