我有大量的嵌套结构,这使得无法分配这种空间并迫使我使用堆。但是我使用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'
我该如何解决这个问题?我甚至走在正确的轨道上吗?
答案 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;