I have to pass a string to a function that strcats something to it, in K&R I read to pass a pointer to it, but I don't know where to allocate buffer...
Is there a difference betw passing an empty string or not?
My printf starts with some strange symbols, and then the string...

int main()  {
    
    char *string;

    //here or in string_concat? or both?
    string = (char*) malloc(16 * sizeof(char)); 

    string_concat( &string );

    printf("%s", string);

    return 0;
}


void string_concat( char **string )  {
    
    //write in string something, need a realloc?
    strcat(*string, something);    

}

>I don't know where to allocate buffer...
Since you're passing the buffer by reference to string_concat, you should allocate the buffer in main, but if string_concat tries to make the string longer than the buffer can hold, you still have a reference to the original pointer and can use realloc.

> Is there a difference betw passing an empty string or not?
The string you pass should always end with a null character because that's what strcat expects for the first argument. You're getting strange symbols because you didn't do that:

string = (char*) malloc(16 * sizeof(char)); 
string[0] = '\0';
string_concat( &string );

Passing by reference only means to pass a pointer, and all arrays are always passed by reference, never by value.

It is not necessary to pass a pointer to a pointer. Passing by reference means to pass a pointer, and String is already a pointer. All that function needs is a pointer to the allocated memory where to do the concantination. Its not necessary to change the value of the original pointer that was allocated in main().

void string_concat( char *string )  {
    
    //write in string something, need a realloc?
    strcat(string, something);    

}

In practice, i saw always is better to pass the pointer as a self-reference, since the pointer data is volatile (and may reference different memory allocations at different time), so, the only constant is the memory allocation of the pointer, that saved me a lot of debugging hours (and spend a lot by not using it)

for your problem, if timing is not critical, you may check the size of the concatenation, and if size > allocation size, then make a call to realloc (be sure to not abuse from this... realloc allocates a new memory space before deallocating previous one)

Ok, I think I've understood the mistery.
Infact I decided to pass a pointer to a pointer because in the interface I'm implementing the function is declared this way, what pros in such a solution (instead of a common char ptr)?

@ InfernalDrake
I'm not sure to have completely got what you mean wits "as a self reference" in this passage:

i saw always is better to pass the pointer as a self-reference, since the pointer data is volatile (and may reference different memory allocations at different time), so, the only constant is the memory allocation of the pointer