You probably saw int main () before, you saw this:
int main(int argc, char** argv)
argv is really a double pointer, but in fact it is not a double pointer, but a pointer to an array of pointers, each of which points to an array of characters related to command line arguments.
This is not a good example, since you probably need a more practical example. I will write the best example and edit my post :)
Edit:
If you are familiar with classes and virtual functions, you may also be aware that any class that has a virtual function is automatically assigned the vftp member variable.
The _vftp element is a pointer to a list of all pointers to your virtual functions. It is inserted at the very beginning of the structure. If you created a new object as follows:
class myclass { public:
When you create an instance of myclass, _vftp is added to the object structure, and this is the very first variable. Since pMyObject is a pointer to this structure in memory, * pMyObject is eqal for _vftp.
Since _vftp is a pointer to an array of pointers to virtual functions, * _vftp is equal to vfunc1 (function pointer).
This means that if we search pMyObject twice and call it, we will call vfunc1 ():
typedef (void* (__thiscall* fnVFunc1))(void); ((fnVFunc)**pMyObject)();
Although this is not a real use for double pointers, it is a prime example of their use. The most common place for double pointers is hacking and reverse engineering, where you usually need to find the pointer in memory and change everything that it points to.