1

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?

3 Answers 3

2

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
Sign up to request clarification or add additional context in comments.

Comments

2

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.

3 Comments

Ok, but why not just have ptr be void *ptr instead of void **ptr, and then have ptr = temp?
It feels like double pointers are redundant, sorry I'm new to C
Answered in the post body.
0

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.