Все двоит и троит...
void f(char** c) {
с = whatever; //меняет локальное значение c. Значение за пределами функции не аффектится
*c = realloc(100500*sizeof(char)); //перевыделяем память. Меняем значение вне функции
**c = 'a';//меняем значение первого символа
}
void g() {
char* c = malloc(1050*sizeof(char));
f(&c);
}