Search code examples
carraysfunctionstructcalloc

using calloc on an array of struct, in a function


This is my struc

//global
typedef struct {
    char idCode[MATLENGTH + 10];
    char *name;
} stud;

In main, I do this

Int main() {

    stud *students;
    createStudentArray(students);
    ....

What I'm trying to do, is:

-pass the array (*student) to a function

-make the function alloc. the array

This is the function i wrote

createStudentArray(stud *students) {

    //I get this value from a file
    int nstud = 3;
    students calloc(nstud, sizeof(students));
    return;
}

the problem is:

-when I try to assign any value to a students field, it doesn't work

ex.

Int main() {

    stud *students;
    createStudentArray(students);
    ....
    strcpy(students[0].name, "Nicola"); //this is where i get the error

My guess is that, in some way, I'm not allocating the array correctly, because, when i try to do

strcpy(students[0].name, "Nicola");

in the createStudentArray function, it wortks just fine. So it looks like I am passing the array by value, and not by reference.

Thanks in advance for your help.


Solution

  • This is because students pointer is passed by value. Any assignment to it inside createStudentArray remains invisible to the caller.

    You have two options to fix this:

    • Return the newly allocated pointer and assign it in the caller, or
    • Accept a pointer-to-pointer, and assign with an indirection operator.

    Here is the first solution:

    stud *createStudentArray() {
        //I get this value from a file
        int nstud = 3;
        stud *students = calloc(nstud, sizeof(students));
        ...
        return students;
    }
    ...
    stud *students = createStudentArray();
    

    Here is the second solution:

    void createStudentArray(stud ** pstudents) {
        //I get this value from a file
        int nstud = 3;
        *pstudents = calloc(nstud, sizeof(students));
        ...
    }
    ...
    stud *students;
    createStudentArray(&students); // Don't forget &