Проблема в вашем коде не в структуре записи, а в структуре базы данных.
Из вашего кода вы хотите, чтобы в базе данных был массив записей, но ее определение и использование не делают этого, как это реализовано прямо сейчас.
Вы хотите, чтобы в качестве первого аргумента база данных имела размер массива переменной длины (как я понимаю из вашего кода), но ее определение и использование неверны.
Когда вы выделяете память для базы данных:
struct database_t * db = malloc (sizeof (struct database_t));
будет выделять размер sturct, который будет размером указателя (записи) плюс размер int (размера), что означает, что указатель записи все еще является только указателем, а не массивом.
Чтобы решить эту проблему, есть несколько вещей, которые вы можете сделать:
Сохранить массив с максимальной длиной
Вы можете изменить определение структуры на что-то вроде этого:
struct database_t {
struct scale_t* entry[MAX_LENGTH];
int size;
};
Это сделает вашу первую операцию malloc работающей и выделит всю необходимую вам память.
Недостатками этого решения является то, что оно будет использовать постоянную длину памяти для всех массивов записей, и вы будете ограничены максимальной длиной базы данных.
Перераспределить память для каждой новой записи
Другим решением проблемы является выделение памяти для массива самостоятельно.
Вы должны перераспределять память массива при каждом запуске цикла for, каждый раз увеличивая используемый вами размер, чтобы сохранить всю память.
Недостатки этого решения заключаются в том, что оно выделяет в программе гораздо больше ресурсов, что делает процесс инициализации более длительным и более сложным.
Новый код функции init должен выглядеть примерно так:
struct database_t *build_database(FILE *fp)
{
struct database_t *db = malloc(sizeof(struct database_t));
int db_idx = 0;
/* Ensure that the value starts from NULL. */
db->entry = NULL;
for (char *line; (line = fgetline(fp)); ++db_idx) {
/* Realloc the memory, adding the new needed memory for the new entry. */
db->entry = realloc(db->entry, sizeof((struct scale_t *) * (db_idx + 1)));
db->entry[db_idx] = malloc(sizeof(struct scale_t));
db->entry[db_idx]->scale = circularlist_create();
char *rest = line;
db->entry[db_idx]->name = strtok_r(line, ",", &rest);
while (isspace(*rest))
++rest;
char *interval;
int note_count = 0;
while ((interval = strtok_r(NULL, "-", &rest))) {
circularlist_insert(&db->entry[db_idx]->scale, interval);
++note_count;
}
db->entry[db_idx]->num_notes = note_count;
}
db->size = db_idx;
return db;
}