4 votes

Les points retournés par les fonctions d'allocation de mémoire

Je suis en train d'apprendre le langage C à partir du livre de K.N.King et je suis en train de faire les projets de programmation du chapitre 17. J'ai rencontré un bug auto-infligé alors que je terminais le premier projet. C'était un comportement indéfini du programme car je passais à realloc() une copie d'un pointeur retourné par un appel précédent à malloc(), puisque l'appel à realloc() se produisait dans une fonction autre que main(). Après avoir relu certaines parties du chapitre, j'ai réalisé que realloc() a un comportement indéfini dans ce cas.

J'ai essayé de rechercher pourquoi c'est le cas sans succès. Est-ce que quelqu'un ici sait pourquoi le pointeur passé à realloc() doit être un pointeur retourné par un appel précédent à malloc(), calloc() ou realloc() et non une copie de ceux-ci ? De plus, ne faisons-nous pas intrinsèquement toujours une copie d'un pointeur retourné par realloc() chaque fois que nous voulons redimensionner un bloc mémoire ?

int num_parts = 0, max_parts = 10;

int main(void)
{
    struct part *inventory = malloc(max_parts * sizeof(*inventory));
    \\...
    switch(ch) {
        \\...
        case 'i':
            insert(inventory, &num_parts, &max_parts);
            break;
        \\...
    }
}

void insert(struct part *inventory, int *num_parts, *max_parts)
{
    if (*num_parts == *max_parts) {
        *max_parts += 10;
        struct part *temp = realloc(inventory, max_parts * sizeof(*temp));
        if (temp != NULL)
            inventory = temp;
        else
            printf("Erreur:...\n");
    }
    \\...
}

4voto

Vlad from Moscow Points 36219

La fonction insert accepte le pointeur inventory par valeur

void insert(struct *inventory, int *num_parts, *max_parts)

et

insert(inventory, &num_parts, &max_parts);

Cela signifie que la fonction travaille avec une copie de la valeur du pointeur original. Changer la copie à l'intérieur de la fonction comme

    if (temp != NULL)
        *inventory = temp;

n'a pas d'influence sur la valeur du pointeur original déclaré dans le main.

Vous devez passer le pointeur par référence à travers un pointeur vers celui-ci.

C'est-à-dire

insert( &inventory, &num_parts, &max_parts);

Et la fonction ressemblera à

void insert(struct **inventory, int *num_parts, *max_parts)
{
    if (*num_parts == *max_parts) {
        *max_parts += 10;
        struct part *temp = realloc( *inventory, max_parts * sizeof(*temp));
        if (temp != NULL)
            *inventory = temp;
        else
            printf("Erreur:...\n");
    }
    \\...
}

Dans ce cas, en déréférençant le paramètre de fonction struct **inventory à l'intérieur de la fonction, nous pouvons accéder directement au pointeur (objet) original et ainsi pouvons le changer.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X