malloc () und realloc () von Strukturen

Sep 30 2020

Können wir Strukturen dynamisch Speicher zuweisen? Ist dies ein korrektes Verfahren, um sich dynamisch zugewiesenen Strukturen zu nähern? Bitte sagen Sie mir, wie malloc()und realloc()eine Struktur.

newnode ist vom Typ struct List *, aber wenn mit der Indizierung begonnen wird, wird es in struct List konvertiert. Wie ist diese Konvertierung möglich? Meine Einfügefunktion akzeptiert nur (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);
}

Antworten

1 chqrlie Sep 30 2020 at 00:34

Der Code funktioniert bis auf 3 Probleme:

  • Sie testen nicht auf Speicherzuordnungsfehler. Beide malloc()und realloc()werden zurückgegeben, NULLwenn kein Speicher zugewiesen werden kann: In newnodediesem Fall erhalten Sie ein undefiniertes Verhalten bei der Dereferenzierung .

  • Um den realloc()Fehlerfall ordnungsgemäß zu behandeln, sollten Sie den neu zugewiesenen Zeiger auf eine andere Variable speichern, damit Sie weiterhin auf das vorherige Array zugreifen können, das nicht freigegeben wurde, und es freigeben können.

  • scanf("%s", newnode[i].val); ist eine Sicherheitslücke: Sie sollten die Anzahl der Bytes begrenzen, mit denen im Zielarray gespeichert werden kann

    scanf("%19s", newnode[i].val);
    
  • Sie testen den Rückgabewert von nicht scanf(), um ungültige oder fehlende Eingaben zu erkennen.

  • insert()nicht einfügen nichts.

Hier ist eine modifizierte Version mit Fehlerbehandlung und weniger verwirrenden Namen:

#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;
}