2015-05-31 4 views
1

У меня есть огромные массивы вложенных структур, что делает невозможным выделение такого пространства и заставляет меня использовать кучу. Но я сталкиваюсь с трудностями, используя 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; 
} 

Он отлично работает, но когда я создаю указатель на указатель на дист как 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' 

Как Я решаю это? Я даже на правильном пути?

+1

Объявление 'struct' не создает вложенные структуры. Он просто объявляет кучу типов структур внутри друг друга. Объявление типа внутри 'struct' без создания именованного поля данных является незаконным в C - декларация даже не компилируется. Просьба представить более содержательную декларацию. Что такое вложенные и какие имена вложенных полей данных? – AnT

+0

Как может 'D' иметь размер 120? Это указатель и два ints. А структуры A, B и C пусты, поэтому их размер должен быть довольно небольшим. – juanchopanza

+0

@juanchopanza 120 - размер массива для структуры D. – solinvictus

ответ

2

Я думаю, что вы отсюда отсюда.

Обратите внимание, что один номер struct year_of_joining составляет приблизительно 100 Мбайт данных. Массив из 100 таких структур требует приблизительно 10 гигабайт данных (и это только запись пола студентов - никакой другой информации вообще).

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 учеников. Это соответствует более чем 25 миллионам студентов каждый год!

Вам понадобится более гибкая схема, в которой каждая из структур содержит указатель на список вложенных структур, поэтому вы можете иметь большие секции, но меньше колледжей и т. Д.Это нужно будет работать больше вдоль линий:

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 разделов.

+0

Это зависит от того, чего вы хотите. Вы можете иметь: 'struct year_of_joining * yoj = malloc (sizeof (* yoj));' и теперь получить доступ к году (но вам нужно его инициализировать). Затем вы можете добавить к нему районы (больше распределений и инициализаций). И так далее. Без четкой спецификации того, что еще вы хотите сделать, невозможно сказать, как вы к нему обращаетесь. Вы извлекаете данные из базы данных? Как вы планируете записывать, что инженерный отдел имеет 10 разделов, в которых участвуют более 100 учеников, но в отделе амазонских языков имеется всего 1 раздел с 4 студентами? И т.д. –

+0

Я получаю данные из файла для указанных учеников.100 лет 150 колледжей совсем не применимы в моем случае, я просто увлекся. – solinvictus

+0

Не зная гораздо больше о том, как организованы ваши данные, на самом деле невозможно сказать, как вам помочь. Задайте новый вопрос, объясняя, где хранятся данные и какая информация вы хотите. –

1

Вы не на правильном пути. Ваша структура действительно огромна, и вам нужно будет перекомпилировать вашу программу, если размер вашего ввода (например, количество студентов) когда-либо становится слишком большим.

Предлагаю вам моделировать свои данные как более мелкие структуры, которые могут быть выделены индивидуально, возможно, с помощью указателей или идентификационных номеров, чтобы связать их вместе.

Другой язык, такой как 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; 
Смежные вопросы