A pointer is simply a variable that holds a memory address.
So you use a pointer to a pointer, when you want to hold the address of a pointer variable.
If you want to return a pointer, and you are already using the return variable for something, you will pass in the address of a pointer. The function then dereferences this pointer so it can set the pointer value. I.e. the parameter of that function would be a pointer to a pointer.
Multiple levels of indirection are also used for multi dimensional arrays. If you want to return a 2 dimensional array, you would use a triple pointer. When using them for multi dimensional arrays though be careful to cast properly as you go through each level of indirection.
Here is an example of returning a pointer value via a parameter:
//Not a very useful example, but shows what I mean...
bool getOffsetBy3Pointer(const char *pInput, char **pOutput)
{
*pOutput = pInput + 3;
return true;
}
And you call this function like so:
const char *p = "hi you";
char *pYou;
bool bSuccess = getOffsetBy3Pointer(p, &pYou);
assert(!stricmp(pYou, "you"));