user2817240
user2817240

Reputation: 195

Double pointers in C

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

Answers (3)

Havenard
Havenard

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

Dwayne Towell
Dwayne Towell

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

Kerrek SB
Kerrek SB

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

Related Questions