« Programmation C/Gestion de la mémoire » : différence entre les versions

Contenu supprimé Contenu ajouté
→‎Exemple : wiki + précisions
Ligne 203 :
 
==== Exemple ====
<tt>realloc</tt> peut être utilisé quand on souhaite boucler sur une entrée dont la longueur peut être indéfinie, et qu'on veut gérer la mémoire assez finement. Dans l'exemple suivant, on suppose définie une fonction '<code>lire_entree'</code> qui :
* lit sur une entrée quelconque (par exemple <tt>stdin</tt>) un entier, et renvoie 1 si la lecture s'est bien passée ;
* renvoie 0 si aucune valeur n'est présente sur l'entrée, ou en cas d'erreur.
Ligne 215 :
int *traiter_entree(size_t *taille, int *erreur)
{
/* On initialise le traitement */
size_t max = 0; /* Nombre d'éléments utilisables */
size_t i = 0; /* Nombre d'éléments utilisés */
int *ptr = NULL; /* Pointeur vers le tableau dynamique */
int valeur; /* La valeur lue depusidepuis l'entrée */
*erreur = 0;
 
while (lire_entree(&valeur) != 0)
/* La boucle */
while (lire_entree(&valeur))
{
if (i >= max)
Ligne 249 ⟶ 247 :
Ici, on utilise <tt>max</tt> pour se souvenir du nombre d'éléments que contient la zone de mémoire allouée, et <tt>i</tt> pour le nombre d'éléments effectivement utilisés. Quand on a pu lire un entier depuis l'entrée, et que <tt>i</tt> vaut <tt>max</tt>, on sait qu'il n'y a plus de place disponible et qu'il faut augmenter la taille de la zone de mémoire. Ici, on incrémente la taille <tt>max</tt> de 10 à chaque fois, mais il est aussi possible de la multiplier par 2, ou d'utiliser toute autre formule. On utilise par ailleurs le fait que, quand le pointeur envoyé à <tt>realloc</tt> est nul, la fonction se comporte comme <tt>malloc</tt>.
 
Le choix de cettela formule de calcul de <code>max</code> à utiliser chaque fois que le tableau est rempli résulte d'un compromis :
* augmenter <tt>max</tt> peu à peu permet de ne pas gaspiller trop de mémoire, mais on appellera <tt>realloc</tt> très souvent.
* augmenter très vite <tt>max</tt> génère relativement peu d'appels à <tt>realloc</tt>, mais une grande partie de la zone mémoire peut être perdue.
Une allocation mémoire est une opération qui peut être coûteuse en terme de temps, et un grand nombre d'allocations mémoire peut fractionner l'espace mémoire disponible, ce qui alourdit la tâche de l'allocateur de mémoire, et au final peut causer des pertes de performance de l'application. Aucune formule n'est universelle, chaque situation doit être étudiée en fonction de différents paramètres (système d'exploitation, capacité mémoire, vitesse du matériel, taille habituelle/maximale de l'entrée...).
Toutefois, l'essentiel est bien souvent d'avoir un algorithme qui marche, l'optimisation étant une question secondaire. Dans une telle situation, utilisez d'abord une méthode simple (incrémentation ou multiplication par une constante), et n'en changez que si le comportement du programme devient gênant.
 
== Problèmes et erreurs classiques ==