Malloc и realloc для объединения структур, связанных с массивом структур - PullRequest
0 голосов
/ 04 июля 2018

Какой лучший способ динамически распределить память для массива структур с включенным объединением? Я должен malloc, а затем realloc до record_user или до data_user? Ниже я объясню больше, это пример кода:

core.h

#define MAX_USER sizeof(record_user) / sizeof(record_user[0])
#define MAX_ARTIST sizeof(record_artist) / sizeof(record_artist[0])
/* all my other defines here */

typedef enum {
    admin = 1,
    basic = 0
} type;

typedef struct {
    int hour;
    int minute;
    int second;
} tm;

typedef struct {
    int day;
    int month;
    int year;
} date;

typedef struct {
    short id;
    char name[MAX_USER_NAME];
    char surname[MAX_USER_SURNAME];
    char email[MAX_USER_EMAIL];
    char password[MAX_PASSWORD_LENGTH];
    date birthday;
    date subscription_date;
    tm subscription_time;
    type role;
} user;

typedef struct {
    short id;
    char name[MAX_ARTIST_NAME];
    char genre[MAX_GENRE][MAX_GENRE_NAME];
    char producer[MAX_PRODUCER_NAME];
    char nationality[MAX_NATIONALITY_NAME];
    int starting_year;
} artist;

/* and other structs */

typedef struct {
    enum { USER, ARTIST } type;
    union {
        user *u_user;
        artist *u_artist;
    };
    int size;
} data;

data.h

#ifndef DATA_H
#define DATA_H

#include "core.h"

extern user record_user[];
extern artist record_artist[];

extern data data_user;
extern data data_artist;
/* etc */

#endif

data.c

#include "data.h"

// SOME PRESET DATA
user record_user[] = {
{ 1, "Name 1", "Surname 1", "name1.surname1@email.com", ",+o[oS", { 29, 9, 1996 }, { 7, 3, 2011 }, { 18, 25, 58 }, 0 },
/** The list goes on **/
}

artist record_artist[] = {
{ 1, "Coldplay", { "Pop", "Britpop", "Alternative Rock" }, "Parlophone", "United Kingdom", 1997 },
/** The list goes on **/
}

data data_user = { .type = USER,.u_user = record_user,.size = MAX_USER };
data data_artist = { .type = ARTIST,.u_artist = record_artist,.size = MAX_ARTIST };

Как видите, существует структура объединения для artist и user. Я решил создать объединенную структуру , чтобы передать множественный массив структур в общую функцию . В полном коде у меня больше союзов, но не стоит перечислять их все. Мне просто нужно понять, что я собираюсь объяснить ниже.

record_user как record_artist имеет некоторые предустановленные данные, которые я связываю с data_user и data_artist соответственно в data.c. Теперь эти данные необходимо увеличить во время выполнения. Я имею в виду, если в record_user есть 100 предустановленных строк данных (то же самое для record_artist), я бы хотел добавить больше строк или даже удалить их. Для этого я знаю, что есть malloc и realloc. Я пытался поиграть с ним, сделать несколько тестов, и я не знаю, как лучше это сделать.

Я попытался объявить в моем main.c файле следующее:

int main() {    
    data_user.u_user = (user *)malloc(size * sizeof(user));
    /***/
}

но я тоже пробовал с этим

int main() {
    record_user = (user *)malloc(size * sizeof(user));
    /***/
}

, но, как я уже представлял, я теряю все предустановленные данные в data.c файле.

МОЯ ЦЕЛЬ

Я бы хотел добиться malloc временного размера для моих данных (для начала 100 ) и затем для связывания массива структур ( или структура объединения), с начальным временным размером , к моим предустановленным данным для их использования. Естественно, во время выполнения я добавлю больше строк, и для этого я буду использовать realloc (или даже удалить их). Это пример кода моей функции добавления:

data *add_data(data *record_data) {
    date record_date;
    tm record_time;

    switch (record_data->type) {
    case USER:
    {
        /* SOMEWHERE HERE I should use realloc to my record_data */
        int ID = record_data->size;
        record_data->u_user[ID].id = ID;
        printf("\n\n\tNEW USER");
        printf("\n\tEnter name: ");
        strcpy(record_data->u_user[ID].name, inputString(MIN_USER_NAME, MAX_USER_NAME));
        printf("\tEnter surname: ");
        strcpy(record_data->u_user[ID].surname, inputString(MIN_USER_SURNAME, MAX_USER_SURNAME));
        printf("\tEnter email: ");
        strcpy(record_data->u_user[ID].email, inputString(MIN_USER_EMAIL, MAX_USER_EMAIL));
        printf("\tEnter password: ");
        strcpy(record_data->u_user[ID].password, inputString(MIN_PASSWORD_LENGTH, MAX_PASSWORD_LENGTH));
        /* etc for birthday, subscription date */

        record_data->size += 1;

        printf("\n\tUser added!");
        return record_data;
    }
    case ARTIST:
        /* asking for input data */

        return record_data;
    }
}

это то, как я вызываю функцию вместо этого в main.c файле

int main() {
    /***/
    data_user = *add_data(&data_user);
    /***/
}

Я не знаю, как двигаться здесь, если мне нужно работать с struct record_user или union struct data_user. Если это то же самое или нет ... если я работаю с исходной структурой (выделяя память), способен ли объединение читать новый объем памяти или нет ? Или лучше работать со структурой объединения, оставляя исходную структуру без изменений?

Надеюсь, кто-то очистит мой разум!

...