Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/68.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 嵌套结构数组_C_Struct_Malloc_Dynamic Memory Allocation - Fatal编程技术网

C 嵌套结构数组

C 嵌套结构数组,c,struct,malloc,dynamic-memory-allocation,C,Struct,Malloc,Dynamic Memory Allocation,我有巨大的嵌套结构数组,这使得不可能分配这种空间,并迫使我使用堆。但是我在使用malloc时遇到了困难。 问题的要点如下 struct year_of_joining { struct district { struct colleges { struct departments { struct sections {

我有巨大的嵌套结构数组,这使得不可能分配这种空间,并迫使我使用堆。但是我在使用
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;
}

我如何解决这个问题?我走对了吗?

你走错了。您的结构非常庞大,如果输入的大小(例如学生人数)过大,您需要重新编译程序

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

另一种语言(如Ruby)可能比C更好,它允许您更多地关注数据,而不是其在内存中存储的细节。一般来说,C语言适合与操作系统进行快速、低级的交互,而带有垃圾编译器和动态类型的语言则更容易编写报告和聚合数据

无论如何,假设您想使用C语言。您选择的数据结构将取决于几件事。您正在建模的数据的精确真实结构是什么?您需要什么性能特征?是否需要快速添加内容,或者快速从数据中提取某些统计数据?如果不知道这些问题的答案,我们很难为您的应用程序提供可用的答案。但是乔纳森·莱夫勒做了一个很好的猜测。以下是我的猜测:

#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;
#包括
结构学生
{
字符*名称;
女性32岁;
uint32加入的第二年;
//索引到一个节数组中。
//您还可以使用指向节的指针(节*)
//但是如果您移动了指针,指针将变得无效
//内存中的节(例如,通过在数组上调用realloc
//(第节)。
uint32截面id;
};
结构截面
{
字符*名称;
uint32部门id;
};
结构部门
{
字符*名称;
uint32学院id;
};
结构学院
{
字符*名称;
uint32区id;
};
结构区
{
字符*名称;
};
//这些TypeDef使我们不必
//在使用结构时写入“struct”。
类型定义结构学生;
typedef结构部分;
类型定义结构部门;
typedef struct学院;
类型定义结构区;
//用于存放物品的动态大小的数组。
学生*学生数组;
节*节_数组;
部门*部门数组;
学院*学院阵列;
地区*地区阵列;

我认为你在这里偏离了正轨

请注意,加入的单个
结构年约为100 MiB的数据。一个由100个这样的结构组成的数组需要大约10Gib的数据(这只是记录学生的性别,没有任何其他信息)

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

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

即使这样也感觉不完全正确,但这将是一种比原来更好的数据组织方式,如果仅仅因为一个系只有一个系,只招收10名学生(因为它是少数兴趣系),那么它只分配足够的空间给一个系和10名学生,而不是为800名学生和8个部分分配空间。

您的
struct
声明不会创建嵌套结构。它只是在彼此内部声明一组结构类型。在
struct
中声明类型而不创建命名数据字段在C中是非法的-该声明甚至不会编译。请提供一个更有意义的声明。什么是嵌套的?嵌套的数据字段名是什么?如何使
D
的大小为120?它是一个指针和两个整数。结构A、B和C是空的,所以它们的大小应该很小。@juanchopanza 120是结构D的数组大小。看起来像噩梦。@solinvictus也许您可以使用多个小结构,并通过malloc()famaily函数动态分配内存。改进代码的设计和组织。这取决于你想要什么。您可以有:
struct year of加入*yoj=malloc(sizeof(*yoj))
现在可以访问年份(但需要对其进行初始化)。然后,您可以向其中添加地区(更多分配和初始化)。等等如果没有更明确的说明您还想做什么,就不可能说出如何访问它。您正在从数据库中提取数据吗?你打算如何记录工程系有10个部门,每个部门有100多名学生,而亚马逊语言系只有1个部门,总共有4名学生?等。我从一个特定学生的文件中获取数据。100年150所大学根本不适用于我的情况。我只是被迷住了。如果不知道更多关于你的数据是如何组织的,就不可能说如何帮助你。请问一个新问题,解释数据存储的位置和您想要的信息。是的,我同意。谢谢。
struct year_of_joining *year = malloc(100 * sizeof(struct year_of_joining));

struct year_of_joining *year = malloc(100 * sizeof(*year));
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;
};