Gestion dynamique de la mémoire

Page 1 sur 4Lecteur de document UniversityLib

Gestion dynamique de la mémoire

Computer Science · notes

Browse all gestion et économie documents

É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

Advertisement

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>

Advertisement

#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));

Advertisement

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);

}

Advertisement

}

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