1

My problem is that I need have the potential to store a number of courses each with a name, and in a course is a number of sections, and a number of students in each section each with a name (obviously), and each student has a number of assignments of type float.

So far I created a nested structure:

struct Student {
    float *Assignments;
};

struct Section {
    char Student_Name[30];
    struct Student *Students;
};

struct Course {
    char Course_Name[10];
    struct Section *Sections;
};

struct Test_Cases {
    struct Course *Courses;
};

Have a pointer to the root structure:

struct Test_Cases *ptr;

And seemingly allocated memory to the root structure and courses with:

ptr = (struct Test_Cases *)malloc(*Num_Cases * sizeof(struct Test_Cases));

ptr->Courses = (struct Course *)malloc(*Num_Courses * sizeof(struct Course));

Is the way I'm going about this correct? Thanks.

chqrlie
  • 131,814
  • 10
  • 121
  • 189
Cobra04
  • 9
  • 2
  • There is no multidimensional array in the code shown. Other than that it looks like an ok start. Not sure what else to say since your question is non-specific. One comment would be that `Test_cases` only contains a single field. If you are planning to add more fields then that's fine otherwise it may not be necessary to have that in a `struct`. – kaylum May 25 '20 at 07:22
  • @kaylum I forgot to mention there's multiple tests scenarios as well. Which is what the structure represents. Is my method of allocating correct? – Cobra04 May 25 '20 at 07:37
  • Design, Code, Test, Debug a single list of pointers, Make Sure It Works correctly, full, empty, whatever. Using That, DCTD a list manged vis a single pointer to the list, (or a metadata struct thereof), MSIW. UT, DCTD a resizeable list, MSIW. UT, make a list of lists of lists...to as many dimensions as you might wish. If you have correctly assembled all the building-blocks, your total assembly will not fall down:) – Martin James May 25 '20 at 07:37
  • part from casting malloc it is an ok start. never cast malloc. if you "need" to cast malloc then you are compiling your code with the wrong compiler switch (C++) – AndersK May 25 '20 at 10:02

3 Answers3

1

yes it seems correct starting.

  • Is my method of allocating correct? For example how would I allocate memory for the amount of sections in a class? – Cobra04 May 25 '20 at 07:38
  • ptr = (struct Section*)malloc(*Num_Sections * sizeof(struct Section)); I'm not sure, I understand you'r question !! hope this help you –  May 25 '20 at 07:46
0

Fortunately, your requirement does not involve any dynamicaly allocated multidimensional array, because it is far from easy in C language.

Here you only need to allocate various arrays of structures. There are 2 common ways to allocate arrays in C:

  1. uninitialized memory:

    struct Test_Cases* ptr = malloc(*Num_Cases * sizeof(struct Test_Cases));
    

    or (IMHO better):

    struct Test_Cases* ptr = malloc(*Num_Cases * sizeof(*ptr));
    

    Remember: you should not cast malloc in C

  2. zero initialized memory:

    struct Test_Cases* ptr = calloc(*Num_Cases, sizeof(struct Test_Cases));
    

    or:

    struct Test_Cases* ptr = calloc(*Num_Cases, sizeof(*ptr));
    

malloc is slightly faster, because its skips the 0 initialization part, but having that initialization may help to write shorter code in which case it should be prefered.

Serge Ballesta
  • 143,923
  • 11
  • 122
  • 252
0

For all these structures, it would be better to add an integer member containing the number of elements allocated for the array:

struct Student {
    char Student_Name[30];
    size_t Num_Assignments;
    float *Assignments;
};

struct Section {
    char Section_Name[30];
    size_t Num_Students;
    struct Student *Students;
};

struct Course {
    char Course_Name[10];
    size_t Num_Sections;
    struct Section *Sections;
};

struct Test_Cases {
    size_t Num_Courses;
    struct Course *Courses;
};

When allocating these arrays, it is safer to use calloc() to get zero inintialized memory and to always test for memory allocation failure:

#include <stdlib.h>

struct Test_Cases *allocate_test_cases(int Num_cases, int Num_courses) {
    struct Test_Cases *ptr = calloc(Num_Cases, sizeof(*ptr));
    if (ptr == NULL)
        return NULL;
    ptr->Num_Courses = Num_Courses;
    ptr->Courses = calloc(Num_Courses, sizeof(*ptr->Courses));
    if (ptr->Courses == NULL) {
        free(ptr);
        return NULL;
    }
    ...
}
chqrlie
  • 131,814
  • 10
  • 121
  • 189