malloc () et realloc () des structures

Sep 30 2020

Pouvons-nous allouer dynamiquement de la mémoire pour les structures? Est-ce une procédure correcte pour aborder des structures allouées dynamiquement? S'il vous plaît dites-moi comment malloc()et realloc()une structure.

newnode est de type struct List * mais au début de l'indexation, il se convertit en struct List. Comment cette conversion est-elle possible? Ma fonction d'insertion n'accepte que (struct List *) Est-ce que je me trompe quelque part?

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

Réponses

1 chqrlie Sep 30 2020 at 00:34

Le code fonctionne sauf pour 3 problèmes:

  • Vous ne testez pas d'échec d'allocation de mémoire. Les deux malloc()et realloc()retourneront NULLsi la mémoire ne peut pas être allouée: vous obtiendrez un comportement indéfini lors du déréférencement newnodesi cela se produit.

  • pour gérer correctement le cas d' realloc()échec, vous devez stocker le pointeur réalloué vers une variable différente afin de pouvoir toujours accéder au tableau précédent qui n'a pas été désalloué et le libérer.

  • scanf("%s", newnode[i].val); est une faille de sécurité: vous devez limiter le nombre d'octets pouvant être stockés dans le tableau de destination avec

    scanf("%19s", newnode[i].val);
    
  • vous ne testez pas la valeur de retour de scanf()pour détecter une entrée non valide ou manquante.

  • insert()n'insérez rien.

Voici une version modifiée avec une gestion des erreurs et des noms moins déroutants:

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