malloc () i realloc () struktur
Czy możemy dynamicznie przydzielać pamięć strukturom? Czy jest to poprawna procedura podejścia do dynamicznie alokowanych struktur? Proszę, powiedz mi, jak to zrobić malloc()i jaką realloc()strukturę.
newnode jest typu struct List *, ale po rozpoczęciu indeksowania konwertuje do struct List.Jak taka konwersja jest możliwa? Moja funkcja wstawiania akceptuje tylko (struct List *) Czy gdzieś się mylę?
#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);
}
Odpowiedzi
Kod działa poza trzema problemami:
Nie testujesz pod kątem niepowodzenia alokacji pamięci. Oba
malloc()irealloc()zwrócą,NULLjeśli nie można przydzielić pamięci: podczas wyłuskiwania danych uzyskasz niezdefiniowane zachowanienewnode.aby z
realloc()wdziękiem poradzić sobie z przypadkiem niepowodzenia, należy zapisać ponownie przydzielony wskaźnik do innej zmiennej, aby nadal można było uzyskać dostęp do poprzedniej tablicy, która nie została zwolniona, i ją zwolnić.scanf("%s", newnode[i].val);jest luką w zabezpieczeniach: należy ograniczyć liczbę bajtów, które mogą być przechowywane w tablicy docelowejscanf("%19s", newnode[i].val);nie testujesz zwracanej wartości w
scanf()celu wykrycia nieprawidłowych lub brakujących danych wejściowych.insert()nic nie wstawia .
Oto zmodyfikowana wersja z obsługą błędów i mniej mylącymi nazwami:
#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;
}