Académique Documents
Professionnel Documents
Culture Documents
Module: M1 - LFSMI - S4
Prof. R. HANNANE
r.hannane@uca.ma
Gestion de la mémoire
Gestion de la mémoire
Introduction
Gestion de la mémoire
Allocation automatique
Que se passe-t-il ?
1 Le programme demande au système d’exploitation la permission
d’utiliser un peu de mémoire
2 Le système d’exploitation donne l’adresse où il peut stocker
cette variable (c’est lui qui contrôle la mémoire !)
3 Lorsque la fonction est terminée, la variable est
automatiquement supprimée de la mémoire
⇒ Lorsqu’on déclare une variable, le système d’exploitation
était automatiquement appelé par le programme
Gestion de la mémoire
Allocation automatique
Gestion de la mémoire
Allocation automatique
Problème:
Ce n’est pas toujours le cas. Cela dépend des machines
Solution:
On utilise l’opérateur sizeof() qui est une fonctionnalité de
base du langage C. Il faut juste indiquer entre parenthèses le
type que vous voulez analyser
Exemple 1:
printf ( " char : % d octets \ n " , sizeof ( char )); // char : 1 octets
printf ( " int : % d octets \ n " , sizeof ( int )); // int : 4 octets
printf ( " double : % d octets \ n " , sizeof ( double )); // double : 8 octets
Gestion de la mémoire
Allocation automatique
int a =8;
⇒
On voit bien que notre variable a de type int qui vaut 8 occupe
4 octets dans la mémoire
Elle commence à l’adresse 4831836000 (c’est son adresse) et
termine à l’adresse 4831836003
La prochaine variable ne pourra donc être stockée qu’à partir de
l’adresse 4831836004 !
Prof. R. HANNANE (FSSM) Programmation II 7 / 39
Gestion de la mémoire
Gestion de la mémoire
Allocation automatique
Gestion de la mémoire
Allocation automatique
Problème:
Même si le tableau est vide, la place en mémoire est
réservée
Solution:
Un des principaux intérêts de l’allocation dynamique est de
permettre à un programme de réserver la place nécessaire
au stockage d’un tableau en mémoire dont il
ne connaissait pas la taille avant la compilation
Prof. R. HANNANE (FSSM) Programmation II 9 / 39
Gestion de la mémoire
Gestion de la mémoire
Allocation dynamique
Allocation dynamique
Les étapes pour l’allocation dynamique
Lors d’une allocation dynamique de mémoire,il faut toujours
suivre ces trois étapes:
1 Appeler une fonction d’allocation pour demander de la
mémoire au système d’exploitation
2 Vérifier la valeur retournée par la fonction d’allocation pour
savoir si le système d’exploitation a bien réussi à allouer la
mémoire
3 Libérer de la mémoire une fois qu’on a fini de l’utiliser
Remarque:
Si on ne libére pas de la mémoire , on s’expose à des fuites de
mémoire, c’est-à-dire que votre programme risque au final de prendre
beaucoup de mémoire alors qu’il n’a en réalité plus besoin de tout cet
espace
Prof. R. HANNANE (FSSM) Programmation II 11 / 39
Gestion de la mémoire
Allocation dynamique
Fonctions d’allocation dynamique
1 La fonction malloc
2 La fonction calloc
3 La fonction realloc
4 La fonction free
Attention:
On va avoir besoin d’inclure la bibliothèque <stdlib.h>
Allocation dynamique
La fonction malloc
la fonction malloc permet d’allouer la mémoire sur le tas
Le prototype de la fonction malloc est:
void * malloc ( size_t taille ) ;
Allocation dynamique
La fonction malloc
Exemple 2:
# include < stdlib .h >
int * p = NULL ; // On cr é e un pointeur sur int
p = ( int *) malloc ( sizeof ( int )); /* La fonction malloc inscrit
dans le pointeur p l ’ adresse qui a é t é reserv é e */
...
Allocation dynamique
La fonction malloc
Note:
Si l’allocation a échoué, c’est qu’il n’y a plus de mémoire libre. Dans un tel cas,
le mieux est d’arrêter immédiatement le programme parce qu’il ne pourra pas
continuer convenablement
⇒ La fonction standard qu’on peut utilier pour arrêter immédiatement le programme
est :exit(). Elle prend un paramètre : la valeur que le programme doit retourner
exit (0) ;
Exemple 3:
# include < stdlib .h >
int main (){
int * p = NULL ;
p = ( int *) malloc ( sizeof ( int ));
if ( p == NULL ){ // Si l ’ allocation a é chou é
exit (0); // On arr ^ e te imm é diatement le programme
} // On peut continuer le programme normalement sinon
...
return 0;
}
Allocation dynamique
La fonction malloc
L’exemple suivant définit un pointeur p sur un objet ∗p de type int,
et affecte à ∗p la valeur de la variable i.
Exemple 4:
# include < stdio .h >
# include < stdlib .h >
int main (){
int i = 3;
int * p = NULL ;
printf ( " valeur de p avant initia lisatio n = % ld \ n " ,p );
p = ( int *) malloc ( sizeof ( int ));
printf ( " valeur de p apres initia lisatio n = % ld \ n " ,p );
*p = i;
printf ( " valeur de * p = % d \ n " ,* p );
return 0;
}
/* Affichage :
valeur de p avant init ialisat ion = 0
valeur de p apres init ialisat ion = 5368711424
valeur de * p = 3
*/
Allocation dynamique
La fonction malloc
Avant l’allocation dynamique, on se trouve dans la configuration
(a)
Allocation dynamique
La fonction malloc
L’allocation dynamique a pour résultat d’attribuer une
valeur à p et de réserver à cette adresse un espace
-mémoire composé de 4 octets pour stocker la valeur de ∗p
(b)
Allocation dynamique
La fonction malloc
(c)
Allocation dynamique
La fonction malloc
Il est important de comparer le programme précédent
qui correspond à la
Exemple 5: situation
...
int i = 3; ⇒
int * p ;
p = ( int *) malloc ( sizeof ( int ));
*p=i;
...
avec celui ci :
qui correspond à la
Exemple 6: situation
...
int i = 3; ⇒
int * p ;
p =& i ;
...
Allocation dynamique
La fonction malloc
Attention:
Dans le dernier programme, les variables i et ∗p sont
identiques (elles ont la même adresse) ce qui implique que
toute modification de l’une modifie l’autre
Allocation dynamique
La fonction malloc
Allocation dynamique
La fonction malloc
Exemple 7:
# include < stdio .h >
# include < stdlib .h >
int main (){
int i = 3;
int j = 6;
int * p ;
p = ( int *) malloc (2 * sizeof ( int ));
*p = i;
*( p + 1) = j ;
printf ( " p = % ld \ n * p = % d \ n p +1 = % ld
\ n *( p +1) = % d \ n " ,p ,* p , p +1 ,*( p +1));
return 0;
}
/* Affichage :
p = 5368711424
*p = 3
p +1 = 5368711428
*( p +1) = 6
*/
Allocation dynamique
La fonction calloc
Allocation dynamique
La fonction calloc
Remarque:
L’emploi de calloc() est simplement plus rapide
Allocation dynamique
La fonction calloc
Exemple 8:
# include < stdio .h >
# include < stdlib .h >
int main (){
int nbr =5;
int * np = ( int *) malloc ( nbr * sizeof ( int )); /* Ici , on ne conna ı
^t
pas la valeur des cases m é moires . La valeur de
chacune des cases m é moires est totalement al é atoire . */
int i ;
if ( np == NULL )
{ /* On v é rifie que le syst è me n ’a pas renvoy é un pointeur nul . */
printf ( " ERREUR : probl è me de memoire . " );
exit (0);
}
for ( i = 0; i < nbr ; i ++)
np [ i ] = 0; /* On met chacune des cases à 0. */
/* suite du programme */
return 0;
}
Allocation dynamique
La fonction calloc
Exemple 9:
# include < stdio .h >
# include < stdlib .h >
int main (){
int nbr =5;
int * np = ( int *) calloc ( nbr , sizeof ( int ));
/* Ici , on conna ı ^ t que les 5 cases m é moires contiennent 0. */
int i ;
if ( np == NULL )
{ /* On v é rifie que le syst è me n ’a pas renvoy é un pointeur nul . */
printf ( " ERREUR : probl è me de memoire . " );
exit (0);
}
/* suite du programme */
return 0;
}
Allocation dynamique
La fonction realloc
Allocation dynamique
La fonction realloc
Le prototype de realloc() :
void * realloc ( void * ptr , size_t size );
Allocation dynamique
La fonction realloc
Note:
Si la zone mémoire précédemment allouée peut être
augmentée sans empiéter sur une zone mémoire utilisée
pour autre chose,
⇒ alors l’adresse mémoire renvoyée n’est pas modifiée (c’est la
même que l’ancienne) mais le nombre de cases mémoires
disponibles est modifié
Allocation dynamique
La fonction realloc
Remarque:
La fonction realloc() ne fait qu’un changement de taille
Allocation dynamique
La fonction realloc
Exemple 10:
# include < stdio .h >
# include < stdlib .h >
int main ()
{
char * maChaine = ( char *) calloc (15 , sizeof ( char ));
if ( maChaine == NULL ){
printf ( " ERREUR : probl è me de memoire . " );
exit (0);
}
Allocation dynamique
La fonction free
Allocation dynamique
La fonction free
Exemple 11:
# include < stdlib .h >
# include < stdio .h >
int main ()
{
int * p = NULL ;
Allocation dynamique
Allocation dynamique et tableaux
Remarque:
Généralement, on ne se sert pas de l’allocation dynamique pour
créer une petite variable. On utilise la méthode automatique qui est
plus simple
L’allocation dynamique se sert pour créer un tableau dont
on ne connaı̂t pas la taille avant l’exécution du programme
Note:
Il est interdit en C de créer un tableau en indiquant sa taille à l’aide
d’une variable : int tab [ nbr ];
Ce code fonctionne sur certains compilateurs mais uniquement dans des
cas précis,
⇒ il est recommandé de ne pas l’utiliser !
Allocation dynamique
Allocation dynamique et tableaux
Allocation dynamique
Allocation dynamique et tableaux
Allocation dynamique
Allocation dynamique et tableaux
Exemple Applicatif:
# include < stdio .h >
# include < stdlib .h >
int main (){
int * tab ;
int i , n ;
n =5;
tab = ( int *) calloc (n , sizeof ( int ));
if ( tab == NULL ) {
printf ( " M é moire non allou é e .\ n " );
exit (0);
}
printf ( " M é moire allou é e avec succ è s avec malloc \ n " );
for ( i =0 ; i < n ; i ++){
*( tab + i )= i ; // *( tab + i ) ou tab [ i ]
}
printf ( " Les é l é ments du tableau sont : \ n " );
for ( i =0 ; i < n ; i ++)
printf ( " %d , " , *( tab + i ));
n =10; // nouvelle taille
tab = realloc ( tab , n * sizeof ( int ));
for ( i =5 ; i < n ; i ++)
*( tab + i )= i ;
printf ( " Les é l é ments du tableau apr è s la r é allocation sont : \ n " );
for ( i =0 ; i < n ; i ++)
printf ( " %d , " , *( tab + i ));
free ( tab ); // liberer l ’ espace reserv é par tab
return 0;
} /* Affichage :
M é moire allou é e avec succ è s avec malloc
Les é l é ments du tableau sont : 0 , 1 , 2 , 3 , 4 ,
Les é l é ments du tableau apr è s la " r é allocation " sont : 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 */
Gestion de la mémoire
Récapitulatif