【问题标题】:Array of nested structures嵌套结构数组
【发布时间】:2015-08-14 05:56:06
【问题描述】:

我有大量嵌套结构,因此无法分配这种空间并迫使我使用堆。但是我在使用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' 

我该如何解决这个问题?我是否走在正确的轨道上?

【问题讨论】:

  • 您的 struct 声明不会创建嵌套结构。它只是在彼此内部声明了一堆结构类型。在 C 中声明 struct 内的类型而不创建命名数据字段是非法的 - 声明甚至无法编译。请提供更有意义的声明。究竟什么是嵌套的,嵌套的数据字段名称是什么?
  • D 的大小怎么可能是 120?它是一个指针和两个整数。并且结构 A、B 和 C 是空的,所以它们的大小应该很小。
  • @juanchopanza 120 是结构 D 的数组大小。
  • 看起来像噩梦。
  • @solinvictus 也许您可以使用多个小型结构,并通过 malloc() famaily 函数动态分配内存。改进代码的设计和组织。

标签: c struct malloc dynamic-memory-allocation


【解决方案1】:

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

请注意,单个 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 个分区分配空间。

【讨论】:

  • 这取决于你想要什么。您可以拥有:struct year_of_joining *yoj = malloc(sizeof(*yoj));,现在可以访问年份(但您需要对其进行初始化)。然后,您可以向其中添加区(更多分配和初始化)。等等。如果没有更清楚地说明您还想做什么,就不可能说出您如何访问它。你是从数据库中提取数据吗?你打算如何记录工程部门有 10 个部门,每个部门有 100 多名学生,但亚马逊语言部门只有 1 个部门,总共有 4 名学生?等等。
  • 我正在从指定学生的文件中获取数据。100 年 150 所大学对我来说根本不适用,我只是被冲昏了头脑。
  • 如果不了解更多有关数据组织方式的信息,实际上无法说出如何为您提供帮助。请提出一个新问题,说明数据的存储位置以及您想要的信息。
  • 是的,我同意。谢谢。
【解决方案2】:

你没有走在正确的轨道上。您的结构非常庞大,如果您的输入(例如学生人数)变得太大,您将需要重新编译您的程序。

我建议您将数据建模为可以单独分配的较小结构,可能使用指针或 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;

【讨论】:

    猜你喜欢
    • 2020-08-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多