Bonjour
Tu as en effet tout à fait le droit d'utiliser realloc() pour ta première allocation en lui passant en effet un pointeur initialisé à NULL. C'est prévu pour et tout à fait autorisé.
Ce qu'il ne faut pas faire, en revanche, c'est utiliser directement le pointeur déjà alloué dans le realloc(). Parce que si le realloc() plante, tu perds le pointeur précédent (celui qui contenait la mémoire allouée) et tu te retrouves en état de fuite mémoire (mémoire allouée non restituable).
Tu dois utiliser un second pointeur, puis si la rellocation a réussi, transférer le second pointeur dans le premier.
Et vis à vis de ton exemple, il est bien conçu mais une reallocation à chaque boucle c'est lourd. Il est préférable d'allouer "n" puis quand "i" dépasse "n" alors là tu réalloue "n de plus".
Et on ne caste pas le malloc/realloc. Ces fonctions renvoient un void* qui est un pointeur universel donc il peut aller partout, le cast est implicite. Et s'il y a une erreur de compilation parce qu'il ne renvoie pas un void* alors c'est que tu as oublié l'include adéquat (ce que tu ne verras pas avec un cast). Le cast nous vient d'un temps que les moins de 20 ans ne peuvent pas connaitre dans lequel le void* n'existait pas et où on utilisait "char*" pour signifier "tout pointeur". Là il fallait alors caster. Le void* est arrivé justement pour supprimer cette
merdenécessité.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| #include <stdio.h>
#include <stdlib.h>
#define SZ_ALLOC (10)
int main() {
unsigned long *tab = NULL;
size_t i = 0;
size_t sz=0;
while (i < 100) { // par exemple
if (i == sz) {
sz+=SZ_ALLOC;
unsigned long *tmp=realloc(tab, sz * sizeof(*tmp));
if (tmp == NULL) {
// Gérer le souci (et généralement on quitte)
free(tab);
return 1;
}
tab=tmp;
}
tab[i] = i; // par exemple
printf("%lu (i=%lu, sz=%lu)\n", tab[i], i, sz);
i++;
}
free(tab);
return 0;
} |
Ensuite tu affines SZ_ALLOC suivant la puissance du host sur lequel tu fais tourner ce code.
Partager