realloc(3)
Fonction de la bibliothèque C
Redimensionne un bloc du tas en gardant son contenu jusqu'à la plus petite des deux tailles. Renvoie NULL sans libérer l'ancien bloc en cas d'échec.
#include <stdlib.h>
void *realloc(void *ptr, size_t size);Description
realloc change la taille d'un bloc déjà alloué. Il peut l'agrandir sur place quand la place suit, ou en allouer un nouveau, recopier les données et libérer l'ancien. Dans les deux cas, la norme C23 garantit que le contenu est préservé « up to the lesser of the new and old sizes » : si tu agrandis, tes anciens octets sont là et les octets ajoutés ont des valeurs indéterminées ; si tu rétrécis, le début est conservé et la fin est perdue.
Deux raccourcis sont codés dans la fonction. realloc(NULL, size) se comporte exactement comme malloc(size). Et, jusqu'à C17 inclus, realloc(ptr, 0) libérait le bloc ; C23 en fait un comportement indéfini, donc ne l'utilise plus pour libérer, écris free(3).
L'adresse change quand le bloc est déplacé. Tous les pointeurs qui visaient l'ancien emplacement, y compris les pointeurs vers l'intérieur du bloc, sont morts après un realloc réussi.
Valeur de retour
L'adresse du bloc redimensionné (parfois la même qu'avant, parfois une nouvelle), ou NULL si l'allocation échoue. Point capital : en cas d'échec, « the original block is left untouched; it is not freed or moved ». L'ancien bloc est donc toujours valide, et toujours à toi à libérer.
Pièges
p = realloc(p, n);perd le bloc sireallocrenvoieNULL: tu as écrasé le seul pointeur vers l'ancien bloc, qui est encore alloué et maintenant introuvable. Passe par un temporaire.
p = realloc(p, n);if (p == NULL) return 1; /* l'ancien bloc est perdu */tmp = realloc(p, n);if (tmp == NULL) { free(p); /* p est toujours valide */ return 1;}p = tmp;Garder un vieux pointeur vers le bloc après l'avoir déplacé : il pointe sur de la mémoire libérée.
Utiliser
realloc(p, 0)pour libérer : comportement indéfini depuis C23, écrisfree(p).Oublier que les octets ajoutés lors d'un agrandissement ne sont pas initialisés.
mem_resize
Réécris realloc sous la forme de mem_resize, qui reçoit l'ancienne taille, déplace le bloc dans un tampon de la nouvelle taille et garde les octets qui tiennent.