École Supérieure de Technologie
et d’Informatique
A.U. 2011/2012
Cours Atelier de programmation avancée
Chapitre: Gestion dynamique de la mémoire (4 pages)
LA ARS - 1ère année
Déclaration statique de données
Chaque variable dans un programme a besoin d'un certain nombre d'octets en mémoire.
o float A, B, C; / réservation de 34 octets=12 octets */
o char E[] = {"Bonjour"}; / réservation de 8 octets (ne pas oublier \0)/
o double g; / réservation de p octets (si on suppose qu’une adresse occupe p octets)*/
o char h; / réservation de p octets */
o float tab[10]; / réservation de 10p octets /
o char J = "Bonjour"; / réservation de p+8 octets */
o char K[] = {"un", "deux", "trois", "quatre"}; / réservation de 4p+3+5+6+7 octets /
(cid:1) quelque soit le type du pointeur (int , char, etc), il occupe toujours la même taille en
mémoire (p octets).
Problème
(cid:2) Souvent, nous devons travailler avec des données dont nous ne pouvons pas prévoir le
nombre et la grandeur lors de la programmation.
(cid:2) Ce serait alors un gaspillage de réserver toujours l'espace maximal prévisible.
(cid:2)
Il faut donc un moyen de gérer la mémoire lors de l'exécution du programme.
La fonction malloc et l'opérateur sizeof
(cid:2) La fonction malloc de la bibliothèque <stdlib> permet de localiser et de réserver de la
mémoire au cours d'un programme
(cid:2) malloc(N) fournit l'adresse d'un bloc en mémoire de <N> octets libres ou la valeur NULL
s'il n'y a pas assez de mémoire.
Exemple
Supposons que nous ayons besoin d'un bloc en mémoire pour un texte de 4000 caractères (un
caractère occupe un octet en mémoire).
char *T;
T = (char *)malloc(4000);
fournit l'adresse d'un bloc de 4000 octets libres et l'affecte à T. S'il n'y a plus assez de
mémoire, T obtient la valeur NULL.
L'opérateur sizeof nous aide à préserver la portabilité du programme.
char B[5][10];
sizeof B
sizeof "Bonjour"
sizeof(float)
sizeof(double)
exit
S'il n'y a pas assez de mémoire pour effectuer une allocation avec succès, il est conseillé
d'interrompre l'exécution du programme à l'aide de la commande exit (de <stdlib>).
s'évalue à 50
s'évalue à 8
Publicité
s'évalue à 4
s'évalue à 8
Mme Wiem Yaiche Elleuch
Gestion dynamique de la mémoire
Page 1
#include<stdio.h>
#include<stdlib.h>
void main()
{
}
int *k;
k=(int ) malloc (3 sizeof(int));
if (!k) exit (-1);
// ou bien if(k==NULL) exit(-1);
if (k!=NULL) printf("%p",k); =>009B1E50
if (k) printf("%p",k); => 009B1E50
La fonction free
Si nous n'avons plus besoin d'un bloc de mémoire que nous avons réservé à l'aide de malloc,
alors nous pouvons le libérer à l'aide de la fonction free de la bibliothèque <stdlib>.
free( <Pointeur> )
(cid:1) libère le bloc de mémoire désigné par le <Pointeur>; n'a pas d'effet si le pointeur a la
valeur NULL.
(cid:2) La fonction free ne change pas le contenu du pointeur; il est conseillé d'affecter la valeur
NULL au pointeur immédiatement après avoir libéré le bloc de mémoire qui y était
attaché.
(cid:2) Si nous ne libérons pas explicitement la mémoire à l'aide free, alors elle est libérée
automatiquement à la fin du programme.
(cid:2) Avec free, on ne peut pas libérer une partie de l’espace alloué.
Exercice: remplir et afficher un tableau dynamique de n entiers.
#include<stdio.h>
#include<stdlib.h>
void main()
{
int *tab, n, i;
printf("saisir nbre éléments");
scanf("%d",&n);
tab=(int )malloc(n sizeof(int));
for (i=0; i<n; i++)
scanf("%d", tab+i);
for (i=0; i<n; i++)
printf("%d", *(tab+i));
free(tab);
tab=NULL ;
}
2ème version: utiliser un pointeur t
#include<stdio.h>
Publicité
#include<stdlib.h>
void main()
{
int tab, t, n;
printf("saisir nbre éléments");
scanf("%d",&n);
tab=(int )malloc(n sizeof(int));
for(t=tab; t<tab+n; t++)
scanf("%d", t);
for(t=tab; t<tab+n; t++)
printf("%d", *t);
free(tab); tab=NULL;
}
Mme Wiem Yaiche Elleuch
Gestion dynamique de la mémoire
Page 2
La fonction realloc
La fonction realloc permet soit de :
(cid:2) Réduire la taille d’un emplacement déjà alloué
(cid:2) Accroître un emplacement donné tout en conservant son contenu.
Exemple d’augmentation de la taille
int *tab ;
tab=(int ) malloc (100 sizeof(int));
if( !tab) exit (-1) ;
tab= (int )realloc (tab, 130 sizeof(int));
if(!tab) exit(-2);
realloc
(cid:2) Cette fonction ne conserve pas obligatoirement l’adresse initiale de la zone, elle assure
(cid:2)
que le contenu de la zone initiale est conservé.
realloc (tab, 130 * sizeof(int)): Le 1er paramètre de cette fonction (càd tab) doit être
l’adresse de début de la zone dont on veut modifier la taille. Le 2rd paramètre (càd 130 *
sizeof(int)) représente la nouvelle taille souhaitée.
(cid:2) Lorsque la nouvelle taille demandée est supérieure à l’ancienne, le contenu de l’ancienne
zone est conservé (quitte à le recopier si la nouvelle adresse est différente de l’ancienne)
(cid:2) Dans le cas où la nouvelle taille est inférieure à l’ancienne, le début de l’ancienne zone
verra son contenu inchangé
Exemple: programme qui remplit et affiche un tableau dynamique de n entiers (en utilisant
les fonctions).
#include<stdio.h>
#include<stdlib.h>
void allocation (int *p, int n)
{
printf("saisir nbre éléments");
scanf("%d",n);
p=(int )malloc((n) sizeof(int));
Publicité
if(!*p) exit (-1);
}
void main()
{
int allocation2 (int n)
{
int *p;
printf("saisir nbre éléments");
scanf("%d",n);
p=(int )malloc((n) * sizeof(int));
if(!p) exit(-1);
return p;
}
int *tab, n;
allocation (&tab,&n);
remplir(tab,n);
afficher(tab,n);
free(tab);
tab=NULL ;
// ou bien
tab=allocation2 (&n);
}
Exercice
Ecrire un programme qui crée une matrice dynamique de l lignes et c colonnes, la remplit et l’affiche.
#include<stdio.h>
#include<stdlib.h>
void saisir (int l,int c)
{
printf("saisir nbre de lignes ");
scanf("%i",l);
printf("saisir nbre de colonnes ");
scanf("%i",c);
}
Mme Wiem Yaiche Elleuch
Gestion dynamique de la mémoire
Page 3
void allocation2 (int *m, int l, int c)
{
int i;
m=(int ) malloc (l sizeof(int *) );
if( !*m) exit(-1);
for (i=0; i<l; i++)
{
(m+i)= (int ) malloc (c sizeof (int ));
if (!(m+i)) exit (-2);
}
Publicité
}
int ** allocation (int l, int c)
{
int i;
int **t;
t=(int *) malloc (l sizeof(int *) );
if(!t) exit(-1);
for (i=0; i<l; i++)
{
(t+i)= (int ) malloc (c * sizeof (int ));
if (!*(t+i)) exit(-2);
}
return t;
}
void remplir (int **t, int l, int c)
{
int i,j;
for (i=0; i<l; i++)
for (j=0; j<c; j++)
scanf("%d", *(t+i)+j);
}
void afficher (int **t, int l, int c)
{
int i,j;
for (i=0; i<l; i++)
{
for (j=0; j<c; j++)
printf("%d", ((t+i)+j));
printf("\n");
}
}
void main()
{
int l,c;
int **t;
saisir (&l,&c);
t=allocation(l,c);
remplir (t,l,c);
afficher (t,l,c);
}
// ou bien allocation2(&t,l,c);
Mme Wiem Yaiche Elleuch
Gestion dynamique de la mémoire
Page 4