I would like to create a fortran binding to a C function that returns an arbitrary length string as a function argument. I have read this similar question, but I simply cannot get the solution there to work. I have simplified the problem as much as I can so I can explain here.
I have a C function like this: c_string.c (I know that usually this kind of function would also have an argument that also returns the length of the string, but I have left it out here for simplicity, since in this example I know the length.)
#include <string.h>
void make_string(char *string) {
    strcpy(string, "sand");
}
It seems to work fine in a C program, for example:
#include <stdlib.h>
#include <stdio.h>
#include "c_string.c"
int main() {
    char *string;
    string = malloc(5*sizeof(char));
    make_string(string);
    printf(string);
}
I want to call this function in a Fortran program: main.f90. So I make a c binding following the solution mentioned above.
program main
    use iso_c_binding
    implicit none
    interface
        subroutine c_make_string(string) bind (C, name='make_string')
            import
            type (c_ptr), value :: string
        end subroutine c_make_string
    end interface
    type (c_ptr) :: c_string
    character, pointer :: local_string(:)
    call c_make_string(c_string)
    call c_f_pointer(c_string, local_string, [4])
    write (*,*) local_string
end program main
But this program results is a segfault at the write statement. Trying to access the resulting local_string pointer by indexing gives a segfault too.
Note: after adding the value attribute to the interface, the segfault is now in the C function.
The only solution I came up with is to not use c_ptr and c_f_pointer(), and just use a maximum buffer length like 512.
program main
    use iso_c_binding
    implicit none
    interface
        subroutine c_make_string(string) bind (C, name='make_string')
            import
            character (len=1, kind=c_char) :: string(512)
        end subroutine
    end interface
    character (len=1, kind=c_char) :: local_string(512)
    call c_make_string(local_string)
    write (*,*) local_string
end program main
But that results in a whole bunch of junk after the useful data in the string. Of course, that is easily worked around if you know the length of the intended string, but it feels unsatisfactory to me... if only I knew what was going wrong with the c_f_pointer() call in the original solution. Should I allocate space for the local_string before, as I do in the C program? But how? Why does it seem I need fixed length arrays for the binding? What is the clean solution to passing char * variables of arbitrary length via subroutine/function arguments?