Q:

Passing struct by reference vs after malloc

What is the difference between these two approaches in terms of data visibility and memory overhead (any other differences would be great as well):

Passing a local struct by reference
Passing a pointer to the allocated memory

typedef struct student_data_t_ {
    char name[30];
    int score;
} student_data_t;

void fill_values (student_data_t *data) {
    snprintf(data->name, 30, "Howard");
    data->score = 20;
    return;
}

int main (void) {
    student_data_t record;
    student_data_t *ptr = NULL;

    fill_values(&record); // <1> passing the struct by reference

    ptr = (student_data_t *)malloc(sizeof(student_data_t));
    if (!ptr) {
        printf("NOMEM");
        return 0;
    }

    fill_values(ptr);  // <2> passing after allocating memory

    if (ptr) {
        free(ptr);
    }

    return 0;
}

A:

For a local variable the memory overhead will exist entirely in the stack for that thread. If you use a large structure in say an embedded system, this can become a concern, as you risk a stack overflow. Generally you will use only the number of bytes requested, but stack space can be limited. (Some applications I work in have a stack of 512 bytes or less)
In the case of using malloc, you are allocating memory from the heap. This avoid the stack size concerns, but adds the requirement that you free the memory when you are done.
Visibility is determined by the variable you store the pointer in.
It is very dangerous to pass a local variable to a seperate thread, and can lead to undefined behavior if the local variable becomes invalid, say due to the function returning.

