Search code examples
cstructmallocdynamic-memory-allocation

Array of nested structures


I have huge arrays of nested structures which makes it impossible to allot that kind of space and forces me to use heap. But I am facing difficulties using malloc. The gist of the problem is below.

struct year_of_joining
{
    struct district
    {
        struct colleges
        {
            struct departments
            {
                struct sections
                {
                    struct students
                    {
                        int sex;
                    }student[100];
                }section_no[8];
            }department_no[17];
        }college[153];
    }dist[13];
};

If I use

int main()
{
    int i=0;    
    struct year_of_joining** year;
    year = malloc(100 * sizeof(struct year_of_joining));
    for (i = 0; i < 100; i++)
    {
        year[i] = malloc(sizeof(struct year_of_joining));
    }

    year[1]->dist[0].college[0].department_no[0].section_no[0].student[8].sex = 1;//works fine
    printf("%d", year[1]->dist[0].college[0].department_no[0].section_no[0].student[8].sex);//prints 1
    free(year);
    return 0;
}

It works fine but when I create a pointer to pointer for dist like year_of_joining and use indirection operator it does not compile:

year[1]->dist[2]->college[0].department_no[0].section_no[0].student[8].sex = 9;//error C2039: 'dist' : is not a member of 'year_of_joining' 

How do I solve this? Am I even on the right track?


Solution

  • I think you are way off track here.

    Note that a single struct year_of_joining is approximately 100 MiB of data. An array of 100 such structures requires approximately 10 GiB of data (and that is only recording the sex of the students — no other information at all).

    struct year_of_joining** year;
    year = malloc(100 * sizeof(struct year_of_joining));
    

    This memory allocation allocates enough space for millions of pointers. You almost certainly intended to use:

    struct year_of_joining *year = malloc(100 * sizeof(struct year_of_joining));
    
    struct year_of_joining *year = malloc(100 * sizeof(*year));
    

    This allocates 100 years worth of the structure.

    However, it seems improbable that you have 13 districts, each of which has exactly 153 colleges, each college having exactly 17 departments, each of which has 8 sections, with each section having exactly 100 students. That corresponds to over 25 million students every year!

    You are going to need a vastly more flexible arrangement, where each of the structures contains a pointer to a list of the nested structures, so you can have bigger sections but smaller colleges, etc. It will need to work more along the lines of:

    struct students
    {
        char name[32];
        int sex;
        // ... and other data ...
    };
    
    struct sections
    {
        char name[32];
        // ... and other data ...
        int n_students;
        struct students *students;
    };
    
    struct departments
    {
        char name[32];
        int n_sections;
        struct sections *sections;
    }
    
    struct colleges
    {
        char name[32];
        // ... and other data ...
        int n_departments;
        struct departments *departments;
    };
    
    struct district
    {
        char name[32];
        // ... and other data ..
        int n_colleges;
        struct college *colleges;
    };
    
    struct year_of_joining
    {
        int  year;
        // ... and other data ...
        int  n_districts;
        struct district *districts;
    };
    

    Even that feels not entirely correct, but it would be a better way of organizing the data than the original, if only because if a department only has one section and enrolls only ten students (because it is a minority-interest department), then it allocates only enough space for one section and ten students, rather than allocating space for 800 students and 8 sections.