malloc () и realloc () структур
Можем ли мы динамически выделять память для структур? Это правильная процедура для подхода к динамически размещенным структурам? Подскажите пожалуйста как malloc()и realloc()структуру.
newnode имеет тип struct List *, но при запуске индексации он преобразуется в struct List. Как это преобразование возможно? Моя функция вставки принимает только (struct List *) Я где-то ошибаюсь?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct List {
char val[20];
};
void insert(struct List *);
int main(void) {
int i = 0;
int size = 1;
struct List *newnode = (struct List *)malloc(size * sizeof(struct List));
for (i = 0; i < 5; i++) {
if (size <= i) {
size = size + size;
newnode = (struct List *)realloc(newnode, size * sizeof(struct List));
}
scanf("%s", newnode[i].val);
insert(newnode[i]);
}
for (i = 0; i < 5; i++) {
printf("%s\n", newnode[i].val);
}
return 0;
}
void insert(struct List *node) {
printf("%s\n", node->val);
}
Ответы
Код работает за исключением 3-х проблем:
Вы не проверяете сбой выделения памяти. Оба
malloc()иrealloc()вернутся,NULLесли память не может быть выделена: вы получите неопределенное поведение при разыменовании,newnodeесли это произойдет.чтобы аккуратно обработать случай
realloc()сбоя, вы должны сохранить перераспределенный указатель в другую переменную, чтобы вы по-прежнему могли получить доступ к предыдущему массиву, который не был освобожден, и освободить его.scanf("%s", newnode[i].val);является недостатком безопасности: вы должны ограничить количество байтов, которые могут быть сохранены в целевом массиве, с помощьюscanf("%19s", newnode[i].val);вы не проверяете возвращаемое значение
scanf()для обнаружения недопустимого или отсутствующего ввода.insert()ничего не вставляет .
Вот модифицированная версия с обработкой ошибок и менее запутанными именами:
#include <stdio.h>
#include <stdlib.h>
struct Item {
char val[20];
};
//void insert(struct Item *);
int main(void) {
int i, j;
int size = 0;
struct Item *array = NULL;
for (i = 0; i < 5; i++) {
if (i >= size) {
int newsize = size ? 1 : size + size;
struct Item *newarray = realloc(array, sizeof(*array) * size);
if (newarray == NULL) {
perror("cannot reallocate the array");
break;
}
size = newsize;
array = newarray;
}
if (scanf("%19s", array[i].val) != 1) {
fprintf(stderr, "missing input\n");
break;
}
//insert(array[i]);
}
for (j = 0; j < i; i++) {
printf("%s\n", array[i].val);
}
free(array);
return 0;
}