嵌套结构的数组

时间:2015-05-31 20:17:25

标签: c struct malloc dynamic-memory-allocation

我有大量的嵌套结构,这使得无法分配这种空间并迫使我使用堆。但是我使用malloc时遇到了困难。 问题的要点如下。

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];
};

如果我使用

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;
}

它工作正常,但是当我创建指向dist的指针时,像year_of_joining并使用间接运算符,它不会编译:

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' 

我该如何解决这个问题?我甚至走在正确的轨道上吗?

2 个答案:

答案 0 :(得分:2)

我认为你在这里偏离轨道。

请注意,单个struct year_of_joining大约是100 MiB的数据。一组100个这样的结构需要大约10 GiB的数据(这只记录学生的性别 - 根本没有其他信息)。

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

此内存分配为数百万个指针分配足够的空间。你几乎肯定打算使用:

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

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

这将分配100年的结构。

然而,你似乎不可能有13个区,每个区有153个学院,每个学院有17个科,每个科有8个科,每个科只有100个学生。这相当于每年超过2500万学生!

你需要一个更加灵活的安排,其中每个结构都包含一个指向嵌套结构列表的指针,所以你可以拥有更大的部分,但是更小的学院等等。它需要更多的工作。以下几行:

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;
};

即使这感觉不完全正确,但如果只是因为一个部门只有一个部分并且只招收十个学生(因为它是少数族裔兴趣部门),那么这将是比原始数据更好的组织数据的方式。 ,它只为一个部分和十个学生分配足够的空间,而不是为800名学生和8个部分分配空间。

答案 1 :(得分:1)

你没有走上正轨。你的结构非常庞大,如果输入的大小(例如学生数量)太大,你需要重新编译你的程序。

我建议你将数据建模为可以单独分配的较小结构,也许使用指针或ID号将它们链接在一起。

像Ruby这样的另一种语言可能是比C更好的选择,使您可以更多地关注数据而不是内存中的存储细节。通常,C适用于与操作系统的快速,低级别交互,而具有垃圾编译器和动态类型的语言将更容易编写报告和聚合数据。

无论如何,假设您要使用C.您选择的数据结构将取决于几个方面。您正在建模的数据的精确真实结构是什么?您需要什么性能特征?是否需要快速添加内容,或快速从数据中提取某些统计信息?在不知道这些问题的答案的情况下,我们很难为您的应用提出可用的答案。但Jonathan Leffler做了很好的猜测。这是我的猜测:

#include <stdint.h>

struct student
{
  char * name;
  uint32_t sex;
  uint32_t year_of_joining;

  // Index into an array of sections.
  // You could also use a pointer to a section (section *)
  // but the pointer would become invalid if you ever moved the
  // sections in memory (e.g. by calling realloc on an array
  // of sections).
  uint32_t section_id;
};

struct section
{
  char * name;
  uint32_t department_id;
};

struct department
{
  char * name;
  uint32_t college_id;
};

struct college
{
  char * name;
  uint32_t district_id;
};

struct district
{
  char * name;
};

// These typedefs make it so we don't have to
// write "struct" when using the structs.
typedef struct student student;
typedef struct section section;
typedef struct department department;
typedef struct college college;
typedef struct district district;

// Dynamically sized arrays for holding things.
student * student_array;
section * section_array;
department * department_array;
college * college_array;
district * district_array;