Home > front end >  C: How to store pointers to structs in a dynamic array within another struct?
C: How to store pointers to structs in a dynamic array within another struct?

Time:05-28

My idea is to have a struct Person which holds the data for a person and a struct Family which contains the number of family members and an array with pointers to the persons. The persons shall be dynamically collected at runtime, stored on the heap, and the Family struct shall contain an array of pointers to these persons (members). Now I have some troubles with this dynamic array and wonder how to properly allocate memory and add these pointers to the array.

This is my current code snippet:

#include <stdio.h>
#include <stdlib.h>
#include <strings.h>

typedef struct Person{
    int age;
    char first_name[256];
    char last_name[256];
} Person;

typedef struct {
    size_t number_members;
    Person **members;
} Family;

void init_person(Person *p);
void add_person_to_family(Family *f, Person *p);
void print_person(Person *p);

int main() {
    size_t number_members = 2;
    Family *f = calloc(1, sizeof(Family));

    for (int i = 0; i < number_members;   i) {
        Person *p = calloc(1, sizeof(Person));
        init_person(p);
        add_person_to_family(f, p);
    }

    for (size_t i = 0; i < f->number_members;   i) {
        print_person(*f[i].members);
    }
    return 0;
}

void init_person(Person *p)
{
    printf("Enter first name: \n");
    scanf("%s", p->first_name);
    printf("Enter last name: \n");
    scanf("%s", p->last_name);
    printf("Enter age: \n");
    scanf("%i", &p->age);
}

void add_person_to_family(Family *f, Person *p)
{
    f->number_members  ;
    f = realloc(f, sizeof(size_t)   (f->number_members) * sizeof(Person *));
    f->members = realloc(f->members, (f->number_members) * sizeof(Person *));
    f->members = p;
}

void print_person(Person *p)
{
    printf("Age: %d\n", p->age);
    printf("First Name: %s\n", p->first_name);
    printf("Last Name: %s\n", p->last_name);
}

CodePudding user response:

f = realloc(f, sizeof(size_t)   (f->number_members) * sizeof(Person *));

The line above makes no sense whatsoever and needs to be just deleted. A Family is a single struct, its size never changes, whether or not some of its fields point to arrays. It contains a size_t field and a pointe field. Sizes of both are constant. You never need to realloc it. By the way, the size of a struct is not the sum of sizes of its fields.

f->members = p;

The line above is an error. f->members points into an array of pointers to Person. You want to update an element of that array. An array element is normally accessed with the [] operator. The line should be

f->members[i] = p;

Determining what i should be is left as an exercise.

*f[i].members

This is also an error. f is not an array and does not point to an array element, so f[i] is not what you want. It is a pointer to a single struct. Fields of a single struct are accessed with the -> operator. members is the one that should be indexed. You need

f->members[i]

Demo

There are other problems, like unsafe use of scanf and not checking return values of library functions including, but not limited to, realloc.

  • Related