Why and when is worth using pointer to pointer?

Well, it is somehow hard to answer to such a general question.

First answer of a C++ programmer will certainly be : Do not use pointers in C++ ! As you have a lot of safer ways to handle problems than pointers, one of your goal will be to avoid them in the first place :)

So pointers to pointers are seldom used in C++. They are mainly used in C. First, because in C, strings are "char*" so when you need a "pointer to a C string" you end with a "char**". Second, as you do not have references in C, when you need to have a function that modify a pointer or that give a pointer as an output value, you need to give a pointer to a pointer parameter. You typically find that in functions that allocate memory, as they give you a pointer to the allocated memory.

If you go the C++ way, try to avoid pointers, you usually have better ways.

my2c


In C, an argument is passed to a function that changes it, through a pointer. You will see the same with C++ for old or legacy code (int main(int argc, char** argv)) , for code that will be accessed from C (COM / XPCOM) or with code that was written by someone used to C (or the C style).

From a "purely C++" standpoint, using pointer to pointer is in most situations a sign of poor coding style, as most situations that require a ** construct can (and should) be refactored to use safer alternatives (like std:: containers, or *& parameters).


I can think of two use cases.

One is arrays as inherited from C. Arrays automatically decay to pointers to their first elements in many cases. If you happen to have an array of pointers, you get a pointer to a pointer for that.
(Something similar can happen when you have a std::vector of pointers, BTW: A pointer is a perfect random access iterator and I have indeed seen std lib implementations using pointers for std::vector<>::iterator. For a std::vector of pointers, v.begin() would return a pointer to a pointer.)

The other is for function arguments. For function arguments, taking something per pointer indicates that callers might call the function even if they don't have an object to pass in; they can pass in NULL then. (Otherwise why take a pointer instead of a reference? See here for more details on this).
Taking a non-const reference to a pointer would indicate that the called function might assign a new address to that pointer.
So taking a pointer to a pointer would indicate that the function might assign a new address to a pointer, if the caller passes in a pointer to it, but is callable with NULL as well. For example:

void f(int** ppi);
void g(int i);

void h()
{
   f(NULL); // call `f()` only for its side-effects

   int* pi = NULL;
   f(&pi);  // call `f()` and get some object in *pi
   if(pi) 
     g(*pi); // use result
}

Tags:

C++

Pointers