I've read and looked at some example of flexible array members but I am not exactly sure how to add and read elements of this variable length array.
typedef struct School {
char *name;
char *courses[]; //Flexible Array Member
} School;
1) Can someone please show me an example of how I can add an element to this Flexible Length Member and print it after it is stored.
2) I also would like to know how to malloc it correctly. Based on what I have read about Flexible Array Members, we would need to add more space for the flexible array member and can't just use sizeof(School);
. My only issue is how do I know how much do add for that flexible member.
You should modify the struct
to add the number of courses present in the allocated structure:
typedef struct School {
char *name;
int ncourses;
char *courses[]; //Flexible Array Member
} School;
Say you have 2 schools, one with 3 courses, one with 2. You would allocate the structures this way:
School *mc = malloc(offsetof(struct School, courses) + 3 * sizeof(char *));
mc->name = strdup("Math College");
mc->ncourses = 3;
mc->courses[0] = strdup("Math 101");
mc->courses[1] = strdup("Math 102");
mc->courses[2] = strdup("Math 103");
School *ps = malloc(offsetof(struct School, courses) + 2 * sizeof(char *));
ps->name = strdup("Psycho School");
ps->ncourses = 2;
ps->courses[0] = strdup("Psycho 101");
ps->courses[1] = strdup("Unknown 404");
As you can see, elements of the variable array are accessed like any other array elements. The malloc
call allocates the appropriate size in bytes for the struct members and the array elements (here char *
pointers), that are located at the end of the structure.
You could use a generic function to allocate and initialize such structures:
School create_school(const char *school_name, int ncourses, char *courses[]) {
School *sp = malloc(offsetof(struct School, courses) + ncourses * sizeof(char *));
sp->name = strdup(school_name);
sp->ncourses = ncourses;
for (int i = 0; i < ncourses; i++) {
sp->courses[i] = strdup(courses[i]);
}
return sp;
}