Vous êtes sur la page 1sur 18

Programmation avancée en C 07/03/2022

Pr. A. KADDARI

Année scolaire 2021/2022

1
Programmation avancée en C 07/03/2022

Introduction
I. Allocation dynamique de la mémoire :
I.1 Les zones mémoire d’un programme en C,
I.2 Les types des variables d’un programme en C,
I.3 Allocation statique,
I.4 Allocation dynamique,
II. Allocation dynamique et application sur les tableaux,
III. Allocation dynamique et application sur les structures.

 Quelle est la mémoire du travail d’une


machine numérique ?
 Comment l’information est elle représentée
dedans ?
 Dans un programme en C, avant de stocker
n’importe quelle donnée il faut lui allouer
un espace mémoire.
Problème : lorsqu’on déclare par exemple un
tableau de 21 étudiants, mais qu’on n’a
finalement que 5 étudiants dans la
promotion!!! Alors gaspillage de mémoire.

2
Programmation avancée en C 07/03/2022

 L’allocation dynamique permet précisément


de résoudre ce type de problème et autres.
 Son rôle est de réserver une zone de mémoire
dont la taille peut être spécifiée à l’exécution
(et non pas à la compilation).
 Les fonctions de gestion dynamique de la
mémoire permettent d’allouer et de libérer de
la mémoire pendant l’exécution.
 Mais avant d’en parler, on doit savoir quelles
sont les zones de mémoire associées à un
programme C ?

Il existe 4 zones de mémoire


où le compilateur range un
programme et ses données :

◦ Une zone1 : la pile (stack).

◦ Une zone2 : le tas (heap).

◦ Une zone3 : mémoire


statique (segment).

◦ Une zone4 : mémoire


programme (code)
Mémoire centrale

3
Programmation avancée en C 07/03/2022

 zone « Code » :
contient le code binaire
de notre programme
compilé.

 zone « statique » :
contient les données
globales du programme
(celles qui sont en vie
durant tout le temps
d'exécution du
programme) Mémoire centrale

zone « tas » :
Utilisée pour stocker les
données allouées
dynamiquement.

 zone « pile » :
Contient des variables
locales, gère le passage
de paramètres et de
contextes lors d'appels
de fonctions, gère la
récursivité, etc. Mémoire centrale

4
Programmation avancée en C 07/03/2022

A 1

2
B
3

C
4

D
E Code binaire
Exemple de programme Zones mémoires
en C correspondantes

 Variables automatiques : créées en pile et détruites au


fur et à mesure de l'exécution des fonctions où elles
sont définies.
 Exemple : variables locales « normales ».

 Variables statiques : créées dans le segment de données


(zone statique), occupant un espace mémoire déterminé
à la compilation, elles persistent jusqu’à l’arrêt du pg.
 Exemple : variables locales déclarées avec le mot clé
static et variables globales.

 Variables dynamiques : dont la création et la destruction


dépendent de demandes explicites faites par le
programme au cours de l'exécution dans le tas (heap).
Elles persistent à la mémoire jusqu’à libération.

10

5
Programmation avancée en C 07/03/2022

11

Introduction
I. Allocation dynamique de la mémoire :
I.1 Les zones mémoire d’un programme en C,
I.2 Les types des variables d’un programme en C,
I.3 Allocation statique,
I.4 Allocation dynamique,
II. Allocation dynamique et application sur les tableaux,
III. Allocation dynamique et application sur les structures.

12

6
Programmation avancée en C 07/03/2022

 L'allocation statique s'occupe des données à taille


fixe dans le programme.

 Le compilateur calcule la taille globale de la


mémoire requise pour ces données avant
l’exécution du programme.

 Les zones concernées par l’allocation statique


sont :
◦ la pile pour les déclarations locales et les paramètres
des fonctions,
◦ la zone globale statique dans le cas des déclarations
globales et des déclarations avec le mot clé static.

13

 La réservation de la  Une variable pointeur est


mémoire s'est déroulée aussi déclaré statiquement.
automatiquement par  Mais, le nombre d'octets p
l'emploi des à réserver pour un pointeur
déclarations statiques dépend de la machine et
des variables. du 'modèle' de mémoire
 Le nombre d'octets à choisi.
réserver pour une  Donc quelque soit le type
variable se calcule de pointeur déclaré, il y
pendant la compilation aura lieu réservation de p
à l’aide de son type. octets en mémoire.

Variables normales Variables pointeurs

14

7
Programmation avancée en C 07/03/2022

C’est quoi des chaînes de caractères constantes ?

 les chaînes de caractères constantes sont


affectées à des pointeurs ou utilisées pour
initialiser des pointeurs sur char.

 La réservation d'espace mémoire pour ce type des


chaines s’effectue aussi automatiquement lors de
compilation.
 Exemple : char *ch="c’est une chaine constante" ;

15

 Calculer l’espace mémoire pour chaque


instruction :
 float A,B,C; 4*3=12 octets
 short D[10][20]; 2*10*20=400 octets
 char E[]={"Bonjour !"}; 1*10=10 octets
 char F[][10]={"un", "deux", "trois", "quatre"};
 double *G; p octets 1*4*10=40 octets
 char *H; p octets
 float *I[10]; 10*p octets
 char *J="bonjour !"; p+1*10 octets
 char *K[]={"un", "deux", "trois", "quatre"};
4*p+3+5+6+7=4*p+21 octets

16

8
Programmation avancée en C 07/03/2022

Introduction
I. Allocation dynamique de la mémoire :
I.1 Les zones mémoire d’un programme en C,
I.2 Les types des variables d’un programme en C,
I.3 Allocation statique,
I.4 Allocation dynamique.
II. Allocation dynamique et application sur les tableaux.
III. Allocation dynamique et application sur les structures.

17

Pourquoi l’allocation dynamique ?


 Souvent, nous devons travailler avec des
données dont nous ne pouvons pas prévoir le
nombre et la grandeur lors de la
programmation.
 Ce serait alors un gaspillage de réserver
toujours l'espace maximal prévisible comme :
char commande[500];
 Et aussi, il serait très utile de pouvoir réallouer
un espace lors de l’exécution.

18

9
Programmation avancée en C 07/03/2022

Un certain nombre de fonctions standards permet


de gérer dynamiquement la mémoire suivant deux
opérations différentes :

 L'allocation dynamique de mémoire : la plus


importante fonction de cette opération est
malloc qui effectue une allocation de base, les
autres étant des variantes ou des fonctions
secondaires.

 La libération de la mémoire : réalisée par la


fonction free qui permettra de réutiliser la
mémoire lors de l’exécution de programme.

19

 Les prototypes des fonctions de gestion


dynamique de la mémoire se trouvent dans le
fichier en‐tête stdlib.h de la bibliothèque
standard du C.

20

10
Programmation avancée en C 07/03/2022

Syntaxe de la fonction :
type_var* ptr=NULL ;
ptr = (type_var*)malloc( nb_octets );
if (ptr==NULL) ...
Ou bien :
nb_octets est à calculer par sizeof

type_var* ptr=NULL ;
ptr = (type_var *)malloc( sizeof(type_var) * nb_var );
if (ptr==NULL) ...

L'utilisation de l'opérateur sizeof est recommandée pour éviter le


calcul « à la main » de nb_octets.

21

tas

 Si une telle allocation est impossible par manque


de place, comme montrée ci-dessus, «malloc»
retourne la valeur de pointeur « NULL ».
 Sinon elle retourne l'adresse du premier octet de
la zone allouée dans le tas. D’où vient l’intérêt du
test if(ptr==NULL) …

22

11
Programmation avancée en C 07/03/2022

 Toutes les valeurs retournées par la fonction


« malloc » sont de type « void * ».
 Pour que le compilateur puisse considérer
autre chose qu'une zone d'octets, il faut
effectuer une conversion explicite de type (un
cast).
 Exemple :

ptr = (type_var *)malloc( sizeof(type_var) * nb_var );

23

 Un des intérêts de l'allocation dynamique est de


libérer l'espace mémoire alloué lorsqu'il n'est
plus nécessaire. Cet espace pourra donc être
réaffecté ultérieurement lors de nouvelles
demandes dynamiques.

 La libération de la mémoire allouée


dynamiquement s'effectue très simplement avec
la fonction free selon la syntaxe suivante :
free( ptr ) ;
ptr=NULL;

24

12
Programmation avancée en C 07/03/2022

1. Toute déclaration d’un pointeur


s’accompagne de son initialisation à NULL.
2. Avant tout appel de malloc(), on doit
s’assurer que le pointeur à allouer est bien
NULL.
3. Après tout appel de malloc(), on s’assure
qu’aucune erreur ne s’est produite.
4. Avant de libérer une zone mémoire, on
s’assure que son pointeur n’est pas NULL.
5. Après libération par free(), on réinitialise
le pointeur à NULL.
25

 En utilisant les 2 fonctions malloc et


free, réaliser un programme qui
permet de :
1. Saisir une chaine de caractères et un
tableau d’entiers de différentes tailles
saisies lors de l’exécution de
programme.
2. Afficher les deux tableaux,
3. Libérer la mémoire.

26

13
Programmation avancée en C 07/03/2022

#include <stdio.h> Printf("Donner la taille d’un tableau


#include <stdlib.h> d’entier :");
void main(){ Scanf("%d" ,&n2);
// un pointeur sur caractères If(t = (int *) malloc(n2 * sizeof(int))){
char * s=NULL; Printf("Donner les éléments du tableau
// un pointeur sur entiers :");
int * t=NULL; for (i = 0;i<n2;i++)
int i,n1,n2; // tailles scanf("%d",&t[i]);
Printf("Donner la taille d’un mot :"); }
Scanf("%d" ,&n1); else
{printf("ERREUR");exit(EXIT_FAILURE);}
//réservation de mémoire
// affichage
if(s = (char *)malloc(n1*sizeof(char))){
-----
Printf("Donner un mot de taille<%d
:",n1); -----
scanf("%s",s);} //libération du mémoire
else {printf(" ERR"); exit(EXIT_FAILURE);} free(t);
free(s);
}

27

 La syntaxe de la fonction calloc :


void * calloc (size_t n, size_t size);
 Le premier argument (size_t n) est le nombre
d'éléments qu'on souhaite pouvoir stocker en
mémoire,
 et le deuxième (size_t size) est la taille de ces
éléments que l'on obtient avec l'opérateur
sizeof().

int *ptr = (int*) calloc(20 ,sizeof (int));

28

14
Programmation avancée en C 07/03/2022

Il existe deux différences majeures entre


malloc et calloc :
 Premièrement en nombre d’arguments :
malloc() prend un seul argument, alors que
calloc() prend deux arguments.
 Deuxièmement, malloc() n’initialise pas la
mémoire allouée, alors que calloc() initialise
la mémoire allouée à ZERO.

29

 La fonction realloc() s'utilise après qu'on ait


utilisé malloc() ou calloc(),
 On peut aussi la rappeler plusieurs fois de
suite (dans une boucle for ou while par
exemple).
 Elle sert à ré-attribuer de la mémoire à un
pointeur mais pour une taille mémoire
différente.

30

15
Programmation avancée en C 07/03/2022

La syntaxe de la fonction realloc :


void* realloc(void *ptr, size_t size);
 Le premier argument est le pointeur sur
lequel on désire effectuer l'opération,
 le deuxième argument est la taille de l'espace
mémoire qu'on veut allouer.

31

 Exemple d’utilisation de realloc


char *maChaine = calloc(15, sizeof(char));
if (maChaine == NULL){
printf("ERREUR : probleme de memoire !\n");
exit(EXIT_FAILURE);
}
/* quelques instructions */
maChaine = realloc(maChaine, 20 * sizeof(char)) ;
if (maChaine == NULL){
printf("ERREUR : probleme de memoire !\n");
exit(EXIT_FAILURE);
}
/* quelques instructions */
free(maChaine);

32

16
Programmation avancée en C 07/03/2022

 Un programme qui permet de créer un tableau de


type entiers selon les étapes suivantes :
1. Demander à l'utilisateur la taille du tableau,
2. Réserver un tableau int de taille saisie (malloc);
3. Saisir le tableau;
4. Réallouer le tableau en éliminant les nombres
impaires (realloc);
5. Afficher le tableau à nouveau;
6. Libérer la mémoire du tableau.

33

int main(){
int n = 0, i = 0;
int* t = NULL;
printf(« Donnez la taille n="); // On demande la taille
scanf("%d", &n);
t = (int*)malloc(n * sizeof(int)); // allocation
if (t == NULL) exit(1); // On arrête tout
// remplissage du tableau
for (i = 0 ; i < n ; i++) {
printf( "t[%d] =", i);
scanf("%d", &t[i]);
}

34

17
Programmation avancée en C 07/03/2022

// On élimine les nombres impaires


//on commence par déclaration d’un tableau tempo
int *t2 = (int*)malloc(n * sizeof(int)), n2=0; // nouvelle taille n2
if (t2 == NULL) exit(1); // On arrête tout
for (i = 0 ; i < n ; i++)//recherche des valeurs paires
if(t[i]%2==0) t2[n2++]=t[i];
if(n2<n){ //c’est-à-dire qu’il en ait trouvé des valeurs impaires
t=(int*)realloc(t,n2*sizeof(int));
if (t == NULL) exit(0); // On arrête tout
for (i = 0 ; i < n2 ; i++) t [i]=t2[i];//recopie des vals paires dans t
}
free(t2); // libération de t2
printf(« Le tableau après traitement:\n")
for (i = 0 ; i < n2 ; i++) printf( "t[%d] =%d\n", i,t[i]);
free(t);
return 0;
}
35

18

Vous aimerez peut-être aussi