When you want to change the value of variable passed to a function as the function argument, and preserve updated value outside of that function, you require pointer(single pointer) to that variable.

void modify(int* p){
  *p = 10;
}

int main(){
  int a = 5;
  modify(&a);
  cout << a << endl;
}

 

Now when you want to change the value of the pointer passed to a function as the function argument, you require pointer to a pointer. Use ** when you want to preserve (OR retain change in) the Memory-Allocation or Assignment even outside of a function call. (So, pass such function with double pointer arg.)

// Double pointer example
void safe_free(int** p) { 
  free(*p); 
  *p = 0; 
}

void allocate(int** p) {
  *p = (int*)malloc(sizeof(int));
}

int main(){
  int* p = NULL;

  // Allocate pointer 
  allocate(&p);
  *p = 42;

  cout << "p:" << p << endl;

  // Free memory
  safe_free(p);
}

 

References : Pointers to Pointers