Page suivante Page précédente Table des matières

5. Allocation dynamique

#include <stdlib.h>
void *malloc(size_t size);
void free(void *ptr);
void *realloc(void *ptr, size_t size);

malloc() demande au système d'exploitation l'allocation d'un espace mémoire de taille supérieure ou égale à size octets. La valeur retournée est un pointeur sur cet espace (NULL en cas d'échec).

free() restitue cet espace au système. realloc() permet d'agrandir la zone allouée.

Il est très fréquent de devoir allouer une zone mémoire pour y loger une copie d'une chaîne de caractères. On utilise pour cela la fonction strdup()

#include <string.h>
char *strdup(const char *s);

L'instruction ``nouveau=strdup(ancien)'' est approximativement équivalente à :

nouveau=strcpy((char *) malloc(1+strlen(ancien)),ancien);

Exemple : la fonction lireligne() ci-dessous lit une ligne de l'entrée standard et retourne cette ligne dans un tampon d'une taille suffisante. Elle renvoie le pointeur NULL si il n'y a plus de place en mémoire.


 
  1     /* lireligne.c */

  2     #include <stdlib.h>
  3     #include <stdio.h>

  4     #define TAILLE_INITIALE 16

  5     char *lireligne(void)
  6     {
  7             /* 
  8                Renvoie un tampon de texte contenant une ligne 
  9                lue sur l'entrée standard. 
 10                Un nouveau tampon est créé à chaque invocation.
 11                Renvoie NULL en cas de problème d'allocation
 12              */

 13             char *chaine;
 14             int taille_allouee, taille_courante;
 15             int c;

 16             chaine = (char *) malloc(TAILLE_INITIALE);
 17             if (chaine == NULL)
 18                     return (NULL);
 19             taille_courante = 0;
 20             taille_allouee = TAILLE_INITIALE;

 21             while (1) {
 22                     c = getchar();
 23                     if ((c == '\n') || (c == EOF))
 24                             break;
 25                     chaine[taille_courante++] = c;
 26                     if (taille_courante == taille_allouee) {
 27                             char *tempo;
 28                             taille_allouee *= 2;
 29                             tempo =
 30                                 (char *) realloc(chaine, taille_allouee);
 31                             if (tempo == NULL) {
 32                                     free(chaine);
 33                                     return (NULL);
 34                             };
 35                             chaine = tempo;
 36                     };
 37             };
 38             chaine[taille_courante] = '\0';
 39             return (chaine);
 40     }

 41     int main(void)
 42     {
 43             char *chaine;
 44             printf("tapez une grande chaîne\n");
 45             chaine = lireligne();
 46             if (chaine == NULL) {
 47                     fprintf(stderr, "Plus de place en mémoire\n");
 48                     exit(EXIT_FAILURE);
 49             }
 50             printf("%s\n", chaine);
 51             free(chaine);
 52             exit(EXIT_SUCCESS);
 53     }
 

Attention : dans l'exemple ci-dessus la fonction lirechaine() alloue un nouveau tampon à chaque invocation. Il est donc de la responsabilité du programmeur de libérer ce tampon après usage pour éviter les fuites mémoire.


Page suivante Page précédente Table des matières