#c #memory #struct #memory_management
Всем, доброго времени суток! Продолжаю своё медленное, но упорное знакомство с СИ. Как правильней всего выделить память под структуру, в которой есть поле... Не уверен что правильный термин, но что-то вроде динамического поля. Смотрим код ниже. typedef struct { int count; char **arrays; } _array_strs; _array_strs *getArrayFromFile() { FILE *fd = getFile(STORAGE, "r"); char sym; char **arrays = (char **)getPtrMatrix(&sym, COUNT_WORDS, BUFF_WORD); struct _array_strs *array_strs = (struct _array_strs *)calloc(sizeof(arrays) + sizeof(int), sizeof(struct array_strs)); int i = 0; while (!feof(fd)) { fgets(arrays[i], BUFF_WORD, fd); i++; } array_strs->count = i; array_strs->arrays = arrays; fclose(fd); return array_strs; } Пару часов убил, много противоречивого нагуглил. Как не пробовал, но компилятор постоянно мною недоволен. При таком варианте кода, его ругательства выглядят следующим образом: src/search.c: In function ‘getArrayFromFile’: src/search.c:32:101: error: invalid application of ‘sizeof’ to incomplete type ‘struct array_strs’ struct _array_strs *array_strs = (struct _array_strs *)calloc(sizeof(arrays) + sizeof(int), sizeof(struct array_strs)); ^ src/search.c:39:12: error: dereferencing pointer to incomplete type ‘struct _array_strs’ array_strs->count = i; ^ src/search.c:44:9: warning: return from incompatible pointer type [-Wincompatible-pointer-types] return array_strs; Буду рад любой помощи компетентных специалистов. Всем добра!
Ответы
Ответ 1
Во-первых, у вас в программе нет такого типа, как struct _array_strs. Поэтому "выделить под него память" у вас не получится. При таком объявлении типа, как у вас, тип вашей структуры называется _array_strs, а не struct _array_strs. Чтобы получить тип struct _array_strs объявление должно быть таким struct _array_strs { int count; char **arrays; }; Вы можете совместить оба варианта typedef struct _array_strs { int count; char **arrays; } _array_strs; что сделает _array_strs и struct _array_strs синонимами. Однако использовать эти имена вперемешку не рекомендуется. Выберите одно. Что характерно, в объявлении функции getArrayFromFile у вас использовано правильное имя типа для вашего исходного варианта (просто _array_strs), но затем в коде вдруг непонятно откуда полез какой-то struct _array_strs. Почему? В общем, сначала определитесь, как именно вы хотите называть свой тип и соответствующим образом исправьте его объявление и ссылки на его название в коде. Во-вторых, в текущей версии под сам объект _array_strs выделить память несложно _array_strs *array_strs = malloc(sizeof *array_strs); ... array_strs->count = i; array_strs->arrays = arrays; и все. У вас же там под calloc понаписана какая-то бессмысленная каша. Если вам зачем-то хочется воспользоваться именно calloc, то _array_strs *array_strs = calloc(1, sizeof *array_strs); ... Имейте в виду, что ваше "динамическое поле arrays" это никакое не "динамическое поле", а обычный указатель. На выделение памяти для самой структуры оно никак не влияет вообще. В вашем коде подразумевается, что память для char **arrays выделена где-то внутри getPtrMatrix и выделена правильно. Не ясно только, почему на результат getPtrMatrix сделан явный каст (char **). Почему? В-третьих, в языке С объявления функции со списком параметров () являются deprecated. Возьмите в привычку писать (void). Хотя функция без параметров - это в большинстве случаев странно. P.S. Ну и, конечно, "классика жанра" - цикл с предусловием while (!feof(fd)), который приведет к вопросам типа "почему у меня array_strs->count на единицу больше, чем надо".
Комментариев нет:
Отправить комментарий