You are on page 1of 13

Cours Langage C/C++

Mmoire et allocation dynamique


Thierry Vaira
BTS IRIS Avignon
tvaira@free.fr v0.1

La mmoire

La pile et le tas

La mmoire dans un ordinateur est une succession doctets (soit 8


bits), organiss les uns la suite des autres et directement
accessibles par une adresse.
En C/C++, la mmoire pour stocker des variables est organise en
deux catgories :
1
2

la pile (stack)
le tas (heap)

Remarque : Dans la plupart des langages de programmation compils,


la pile (stack) est lendroit o sont stocks les paramtres dappel et
les variables locales des fonctions.

tv (BTS IRIS Avignon)

Cours C/C++

tvaira@free.fr v0.1

2 / 13

La mmoire

La pile (stack)

La pile (stack) est un espace mmoire rserv au stockage des


variables dsalloues automatiquement.
Sa taille est limite mais on peut la rgler (appel POSIX setrlimit).
La pile est btie sur le modle LIFO (Last In First Out) ce qui signifie
"Dernier Entr Premier Sorti". Il faut voir cet espace mmoire comme
une pile dassiettes o on a le droit dempiler/dpiler quune seule
assiette la fois. Par contre on a le droit dempiler des assiettes de
taille diffrente. Lorsque lon ajoute des assiettes on les empile par le
haut, les unes au dessus des autres. Quand on les "dpile" on le fait
en commenant aussi par le haut, soit par la dernire pose.
Lorsquune valeur est dpile elle est efface de la mmoire.

tv (BTS IRIS Avignon)

Cours C/C++

tvaira@free.fr v0.1

3 / 13

La mmoire

Le tas (heap)

Le tas (heap) est lautre segment de mmoire utilis lors de


lallocation dynamique de mmoire durant lexcution dun
programme informatique.
Sa taille est souvent considre comme illimite mais elle est en ralit
limite.
Les fonctions malloc et free, ainsi que les oprateurs du langage
C++ new et delete permettent, respectivement, dallouer et
dsallouer la mmoire sur le tas.
La mmoire alloue dans le tas doit tre dsalloue explicitement.

tv (BTS IRIS Avignon)

Cours C/C++

tvaira@free.fr v0.1

4 / 13

La mmoire

Sous Linux, on peut visualiser facilement les valeurs du tas et de la pile :


$ ulimit -a
...
data seg size
...
stack size
...

(kbytes, -d) unlimited


(kbytes, -s) 8192

La taille de la pile tant limite (ici 8Mo), cela peut provoquer des
crasements de variables et surtout des "Erreur de segmentation" en cas
de dpassement. Il est videmment recommand dallouer dans le tas les
"grosses" variables sous peine de surprise !

tv (BTS IRIS Avignon)

Cours C/C++

tvaira@free.fr v0.1

5 / 13

Allocation dynamique

malloc et free
Lallocation dune nouvelle zone mmoire se fait dans un endroit
particulier de la mmoire appele le tas (heap).
Elle se fait par la fonction malloc : void *malloc(size_t
taille) ;
Largument transmis correspond la taille en octets de la zone
mmoire dsire.
La valeur retourne est un pointeur void * sur la zone mmoire
alloue, ou NULL en cas dchec de lallocation.
Si vous devez redimensionner un espace mmoire qui a t allou
dynamiquement, il faudra utiliser la fonction realloc().
La mmoire alloue doit, un moment ou un autre, tre libre.
Cette libration mmoire se fait par la procdure free : void
free(void *pointeur) ;
tv (BTS IRIS Avignon)

Cours C/C++

tvaira@free.fr v0.1

6 / 13

Allocation dynamique

Exemple : allocation mmoire


int *p; // pointeur sur un entier
int *T; // pointeur sur un entier
// allocation dynamique dun entier
p = (int *)malloc(sizeof(int)); // alloue 4 octets (= int) en mmoire
*p = 1; // ecrit 1 dans la zone mmoire alloue
// allocation dynamique dun tableau de 10 int
T = (int *)malloc(sizeof(int) * 10); // alloue 4 * 10 octets en mmoire
// initialise le tableau avec des 0 (cf. la fonction memset)
for(int i=0;i<10;i++) {
*(T+i) = 0; // les 2 critures sont possibles
T[i] = 0;
// identique la ligne prcdente
}
// ou plus directement
memset(T, 0, sizeof(int)*10); // il faudra alors inclure string.h
free(p);
free(T);

Une fois quune zone mmoire a t libre, il ne faut sous aucun prtexte y accder, de
mme quil ne faut pas tenter de la librer une seconde fois.
tv (BTS IRIS Avignon)

Cours C/C++

tvaira@free.fr v0.1

7 / 13

Allocation dynamique

Rgles de bonne conduite


Un certain nombre de rgles, quand elles sont observes, permettent de se
mettre labri de problmes :
Toute dclaration de pointeur saccompagne de son initialisation
NULL
Avant tout appel de malloc(), on doit sassurer que le pointeur
allouer est bien NULL
Aprs tout appel de malloc(), on sassure quaucune erreur ne sest
produite
Avant de librer une zone mmoire, on sassure que son pointeur nest
pas NULL
Ds quune zone mmoire vient dtre libre par free(), on
rinitialise son pointeur NULL

tv (BTS IRIS Avignon)

Cours C/C++

tvaira@free.fr v0.1

8 / 13

Allocation dynamique

new et delete

Pour allouer dynamiquement en C++, on utilisera loprateur new.


Celui-ci renvoyant une adresse o est cre la variable en question, il
nous faudra un pointeur pour la conserver.
Manipuler ce pointeur, reviendra manipuler la variable alloue
dynamiquement.
Pour librer de la mmoire alloue dynamiquement en C++, on
utilisera loprateur delete.

tv (BTS IRIS Avignon)

Cours C/C++

tvaira@free.fr v0.1

9 / 13

Allocation dynamique

Pour allouer dynamiquement en C++, on utilisera loprateur new.


Exemple : allocation dynamique
#include <iostream>
#include <iostream>
#include <new>
using namespace std;
int main ()
{
int * p1 = new int; // pointeur sur un entier
*p1 = 1; // ecrit 1 dans la zone mmoire alloue
cout << *p1 << endl; // lit et affiche le contenu de la zone mmoire alloue
delete p1; // libre la zone mmoire alloue
return 0;
}

tv (BTS IRIS Avignon)

Cours C/C++

tvaira@free.fr v0.1

10 / 13

Allocation dynamique

Exemple : allocation dynamique dun tableau


#include <iostream>
#include <new>
using namespace std;
int main ()
{
int * p2 = new int[5]; // alloue un tableau de 5 entiers en mmoire
// initialise le tableau avec des 0 (cf. la fonction memset)
for(int i=0;i<5;i++)
{
*(p2 + i) = 0; // les 2 critures sont possibles
p2[i]
= 0;
// identique la ligne prcdente
cout << "p2[" << i << "] = " << p2[i] << endl;
}
delete [] p2; // libre la mmoire alloue
return 0;
}

tv (BTS IRIS Avignon)

Cours C/C++

tvaira@free.fr v0.1

11 / 13

Allocation dynamique

Pour allouer dynamiquement un objet, on utilisera loprateur new.


Exemple : allocation dynamique dun objet
#include <iostream>
#include "point.h"
using namespace std;
int main()
{
Point *pointC; // je suis pointeur sur un objet de type Point
pointC = new Point(2,2); // jalloue dynamiquement un objet de type Point
pointC->afficher(); // Comme pointC est une adresse, je dois utiliser loprateur -> pour accder aux
membres de cet objet
pointC->setY(0); // je modifie la valeur de lattribut _y de pointB
(*pointC).afficher(); // cette criture est possible : je pointe lobjet puis jappelle sa mthode
afficher()
delete pointC; // ne pas oublier de librer la mmoire alloue pour cet objet
return 0;
}

tv (BTS IRIS Avignon)

Cours C/C++

tvaira@free.fr v0.1

12 / 13

Allocation dynamique

Fuite de mmoire
Lallocation dynamique dans le tas ne permet pas la dsallocation
automatique.
Chaque allocation avec "new" doit imprativement tre libre
(dtruite) avec "delete" sous peine de crer une fuite de mmoire.
La fuite de mmoire est une zone mmoire qui a t alloue dans le
tas par un programme qui a omis de la dsallouer avant de se
terminer. Cela rend la zone inaccessible toute application (y compris
le systme dexploitation) jusquau redmarrage du systme. Si ce
phnomne se produit trop frquemment la mmoire se remplit de
fuites et le systme finit par tomber faute de mmoire.
Ce problme est vit en Java en introduisant le mcanisme de
"ramasse-miettes" (Garbage Collector ).
tv (BTS IRIS Avignon)

Cours C/C++

tvaira@free.fr v0.1

13 / 13

You might also like