c

c how to pass a reference to a struct array instead of setting the copy of the struct


I want to add the reference of a struct to an struct array. But i can only deference the struct and set a copy of the struct to the index. Is there a way to give the indexes of students the address of the Student structs passed in the add_student function?

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>

typedef struct student {
    int age;
    char *name;
} Student;

Student *students;

int size = 0;

void add_student(Student *student) {
    Student *temp;
    size++;
    temp = realloc(students, sizeof(Student)*size);
    if(!temp) {
        printf("Cannot realloc memory\n");
        exit(1);
    }
    temp[size-1] = *student;
    students = temp;
}

int main(int argc, char **argv) {

    students = malloc(0);
    Student student;
    student.name = "name1";
    student.age = 11;
    add_student(&student);
    Student student2;
    student2.name = "name2";
    student2.age = 13;
    add_student(&student2);

    student2.age = 22;
    student2.name = "name33";
// I change the student2 and i would except that the Student struct gets changed in students[1]

    return 0;
}

Solution

  • A struct array contains struct elements, not references to struct elements. You need to have an array of pointers instead, like

    Student **students;
    

    and continue in this manner when you realloc, so temp will have the same type. And then you can do this:

    temp[size-1] = student;
    

    because then temp will be an array of Student pointers and therefore you will be able to store references as its elements.

    For more information, read https://www.geeksforgeeks.org/how-to-declare-and-initialize-an-array-of-pointers-to-a-structure-in-c/

    which specifies this as the general form for such dynamic structure pointer arrays:

    < structure_name >  ** < array_name > = <structure_name **> malloc ( sizeof( <structure_name> )* size ) ;
    

    The same page provides this sample code for illustration:

    // C Program to implement
    // Dynamic Array of structure
    // pointer
    #include <stdio.h>
    #include <stdlib.h>
     
    typedef struct node {
        int number;
        char character;
    } node;
     
    int main(void)
    {
        // First pointer to structure
        node* structure_ptr1 = (node*)malloc(sizeof(node));
        // Second pointer to structure
        node* structure_ptr2 = (node*)malloc(sizeof(node));
        // Third pointer to structure
        node* structure_ptr3 = (node*)malloc(sizeof(node));
        // Fourth pointer to structure
        node* structure_ptr4 = (node*)malloc(sizeof(node));
     
        // Initializing structure pointers
     
        structure_ptr1->number = 100;
        structure_ptr1->character = 'a';
     
        structure_ptr2->number = 200;
        structure_ptr2->character = 'b';
     
        structure_ptr3->number = 300;
        structure_ptr3->character = 'c';
     
        structure_ptr4->number = 400;
        structure_ptr4->character = 'd';
     
        // Declaring the array dynamically for structure
        // pointers
     
        // Note that double pointer is
        // used for pointer to pointer
        node** structure_array
            = (node**)malloc(sizeof(node) * 4);
     
        // Initializing the array of structure pointers
     
        structure_array[0] = structure_ptr1;
        structure_array[1] = structure_ptr2;
        structure_array[2] = structure_ptr3;
        structure_array[3] = structure_ptr4;
     
        // Accessing dynamic 1D arrays - just like static 1D
        // arrays
        printf("Data:\n");
        for (int i = 0; i < 4; i++) {
            printf("%c - ", structure_array[i]->character);
            printf("%d\t\t", structure_array[i]->number);
            printf("\n");
        }
    }