Q:

Where should I use a type char ** in some case as the input parameter?

There is some code piece right here below:
main ()
  {
    char in[8];
    char out[255];
    iconv_t cd;
    cd = iconv_open("gb18030", "utf-8");     
        ...
    char *p_in = in;
    char *p_out = out;
    size_t inlen = strlen(in);
    size_t outlen = sizeof(out);
    if (iconv(cd, &p_in, &inlen, &p_out, &outlen) < 0)
    {
          ...
        return -1
    }
          ...
        return 0;
  }

I can't totally understand the 2nd and 3rd parameters of the call to iconv. Why should that be ** pointer not the * pointer as the input?  Can anyone explain the cases in C when the ** pointer should be used? 

A:

Pointer to pointer is used where the passed pointer is need to be modified in the called function and that modification need to be seen in the caller function. This is required because in C arguments are passed by value. So, when an argument is passed to a function then it simply copied to the function's parameter and created a local copy having block scope. Any change to that variable will not be seen in the argument that has been passed.  
void foo(in x){
    x = 10;
}

int main(void){
     int x = 5;
     foo(x)
     printf("%d\n", x);  // x will be 5
}

Same happens with pointers  
void bar(char *p){
    p = "foobar";
}

int main(void){
     char *p = NULL;
     bar(p);
     if(p)
         printf("p is pointing to %s\n", p);
     else 
         printf("p is NULL\n");   // This will 
}

Using a pointer to pointer will do the desired job (pointing p to the string "foobar" 
void bar(char **p){
        *p = "foobar";
    }
int main(void){
     char *p = NULL;
     bar(&p);
     if(p)
         printf("p is pointing to %s\n", p);
     else 
         printf("p is NULL\n");   // This will 
}  

Another use is when an array of string is need to passed to a function. Like 
int main(int argc, char **argv)  

or  
void print_fruits(char **fruits, size_t len){
    for(int i = 0; i < len; i++)
        printf("%s\n", fruits[i]);
}

int main(void){
    char *fruits[5] = {"Apple", "Banana", "Cherry", "Kiwi", "Orange"};
    print_fruits(fruits, sizeof(fruits)/sizeof(fruits[0]));
}

Note that in function call print_fruits, fruits in the argument list will decay to pointer to its first element and the expression fruits will become of type char ** after the conversion.

