2 votes

Réduire la taille d'un tableau avec realloc, en perdant le premier élément

J'ai essayé de créer un programme d'exemple utilisant calloc et realloc et je suis tombé sur un problème où, lorsque je réduis un tableau d'entiers, il semble supprimer le premier élément au lieu du dernier.

int *m = (int*)calloc(2, sizeof(int));

    *m = 1;     
    *(m+1) = 2;   
    printf("\tInt 1: %d\n", m[0]);
    printf("\tInt 2: %d\n\n", *(m+1));

// REALLOC

printf("How many elements the array have? ");
scanf("%d", &num);

*m = (int *)realloc(m, num * sizeof(int));

    printf("ARRAY NOW HAS %d PLACES\n\n\t", num);

    for(i = 0; i < num; i++) {

        m[i] = i + 1;
        printf("%d ", m[i]);

    }

// DELETING MEMBERS OF AN ARRAY

while((d < 0) || (d > num)) {

    printf("\n\nChoose which position of the previous array should be deleted (0 = first): ");
    scanf("%d", &d);
}

printf("\nUPDATED ARRAY:\n\n");

for(i = d; i < num - 1; i++) {

    m[i] = m[i + 1];
}

*m = (int *)realloc(m, (num - 1)*sizeof(int));

num--;

for(i = 0; i < num; i++) {

    printf("%d ", m[i]);
}

Un exemple de la sortie du programme serait :

        Int 1: 1
        Int 2: 2

How many elements the array have? 17
ARRAY NOW HAS 17 PLACES

        1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17

Choose which position of the previous array should be deleted (0 = first): 6

UPDATED ARRAY:

10620272 2 3 4 5 6 8 9 10 11 12 13 14 15 16 17

Et si j'inclus le dernier membre du tableau qui aurait dû être supprimé (dans ce cas, m[16]), il apparaît :

10620272 2 3 4 5 6 8 9 10 11 12 13 14 15 16 17 17

Bien sûr, je ne suis pas tout à fait sûr de ce qui se passe mais il semble que cela supprime simplement la valeur de m[0] ?

Merci d'avance pour toute aide !

2voto

dasblinkenlight Points 264350

La raison pour laquelle la valeur initiale est modifiée est que vous l'affectez :

*m = (int *)realloc(m, num * sizeof(int));

debe ser

m = realloc(m, num * sizeof(int));

Votre code devrait également produire un avertissement, vous indiquant que l'assignation d'un pointeur à un élément de tableau contenant int est invalide. La correction de cet avertissement devrait avoir réglé votre problème.

Notez qu'une affectation de la forme

m = realloc(m, ...);

donde m est utilisé des deux côtés de realloc est intrinsèquement dangereux, car realloc pourrait potentiellement retourner NULL - par exemple, lorsqu'il n'y a pas assez de mémoire à allouer. L'affectation aveugle à m rendrait l'ancienne valeur de m inaccessible, empêchant une désaffectation correcte. En production, vous devez attribuer realloc dans un fichier temporaire, puis vérifiez que le résultat de l'opération NULL et seulement ensuite, réaffecter le résultat à m .

0voto

chux Points 13185

En plus de @dasblinkenlight bonne réponse, lorsque l'on réduit la taille de l'allocation et que la réallocation échoue (un événement rare), le code peut simplement continuer avec le pointeur original.

Suggestion de réécriture, en supposant num > 0 :

// *m = (int *)realloc(m, num * sizeof(int));
void *t = realloc(m, sizeof *m * num);
if (t) {
  m = t;
}

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