malloc () i realloc () struktur

Sep 30 2020

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

1 chqrlie Sep 30 2020 at 00:34

Kod działa poza trzema problemami:

  • Nie testujesz pod kątem niepowodzenia alokacji pamięci. Oba malloc()i realloc()zwrócą, NULLjeśli nie można przydzielić pamięci: podczas wyłuskiwania danych uzyskasz niezdefiniowane zachowanie newnode.

  • 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 docelowej

    scanf("%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;
}