54

I've seen some code, as well as some errors generated from my compiler that have a '**' token before the variable (eg **variablename unreferenced-- or something, I can't recall exactly offhand). I'm fairly certain this is related to pointers, if I had to guess it looks like it's trying to dereference twice. '**' is fairly ungoogleable. Can someone point me to a good website/documentation or would someone care to explain it here?

Thanks.

Great responses. If I can add, what would be some situations where it is useful to have a pointer to a pointer? Shouldn't you just be using the original pointer instead of creating yet another pointer to the original pointer?

agscala
  • 3,835
  • 5
  • 27
  • 25

11 Answers11

57

** is not actually only pointer to pointer (as in declaration), but is also the dereference of a dereference (in a statement).

It is used often in C which does not have the & notation for references, e.g. to update a return value which is a pointer type:

int alloc_foo(struct foo **foo_ret)
{
    *foo_ret = malloc(sizeof(struct foo));
    return 1; /* to indicate success; return value in foo_ret */
}
TheGoldenTree
  • 158
  • 4
  • 16
Antti Huima
  • 25,136
  • 3
  • 52
  • 71
48

You may recognize the signature for main():

int main(int argc, char* argv[])

The following is equivalent:

int main(int argc, char** argv)

In this case, argv is a pointer to an array of char*.

In C, the index operator [] is just another way of performing pointer arithmetic. For example,

foo[i]

produces the same code as

*(foo + i)
Parappa
  • 7,566
  • 3
  • 34
  • 38
14

It's not a ** token. It's simply a * token followed by another * token. In your case, you have a pointer to a pointer, and it's being dereferenced twice to get whatever's really being pointed to.

Rob Kennedy
  • 161,384
  • 21
  • 275
  • 467
12

** is a pointer to a pointer.

It might be a matrix (an array of arrays) or an array of strings (a char array), etc.

NelsonGon
  • 13,015
  • 7
  • 27
  • 57
Can Berk Güder
  • 109,922
  • 25
  • 130
  • 137
7

It's a double dereference.

int i = 3;
int* ptr_to_i = &i;
int** ptr_to_ptr_to_i = &ptr_to_i;

std::cout << **ptr_to_ptr_to_i << std::endl;

Prints 3.

Paul Beckingham
  • 14,495
  • 5
  • 33
  • 67
6

I just wanted to underscore some of the uses for a pointer to a pointer. Most of these are touched on by other posts, but I thought reiteration might help.

  • It allows a callee to modify a pointer owned by the caller. For example, one could pass a pointer to a pointer to the beginning of a string, and the callee could modify the pointed-to pointer to now point to a position within the string where a particular character occurs.

  • Because arrays degrade to pointers (and pointers can be treated as arrays), you will often see a pointer to a pointer if you have:

    • A pointer to an array. This is a generalization of the above case, since a "string" (a C-style string, anyway) is really just an array of chars.

    • An array of pointers. You might, for example, have an array of pointers to objects, allowing for polymorphism, or an array of pointers to select objects stored in another collection.

    • An array of arrays. Again, arrays degrade to pointers, so this is a specific case of the above. This is often used for so called "jagged" arrays (as opposed to rectangular).

P Daddy
  • 28,912
  • 9
  • 68
  • 92
5

You can interpret it literally -- pointer to a pointer

BC.
  • 24,298
  • 12
  • 47
  • 62
3
  • int **var declares a pointer to a pointer
  • **var references the content of a pointer, which in itself points to a pointer
Tony the Pony
  • 40,327
  • 71
  • 187
  • 281
1

One common use is that it allows a function to set the pointer to null.
So free(pointer) frees up the memory allocated to pointer but leaves the pointer dangerously pointing at the free memory.
Instead declare a my_free(**pointer) and call my_free(&pointer) so my_free() can set the pointer to null after freeing it.

Martin Beckett
  • 94,801
  • 28
  • 188
  • 263
1

See http://www.c2.com/cgi/wiki?ThreeStarProgrammer

Joshua
  • 40,822
  • 8
  • 72
  • 132
0

It's one of the allures of C++ Sigils. From my own personal experience, I can vouch faster and more efficient read-access performance using dereference operators on STL's Arrays & Vectors. I've also adopted habitual shared pointer methods if you're curious. :)