Vous êtes sur la page 1sur 21

Les pointeurs

M. Hadjila

4 novembre 2018

1 / 21
Une question d’adresse

Lorsque l’on déclare une variable, l’ordinateur nous prête une place
dans sa mémoire et y accroche une étiquette portant le nom de la
variable.

2 / 21
Une question d’adresse
2

On pouvait donc représenter la mémoire utilisée dans ce


programme comme suit :

Figure : La mémoire lorsque l’on déclare une variable

3 / 21
Une question d’adresse
3

La mémoire d’un ordinateur est réellement constituée de cases.


Il y en a même énormément, plusieurs milliards sur un
ordinateur récent !
Il faut donc un système pour que l’ordinateur puisse retrouver
les cases dont il a besoin.
Chacune d’entre elles possède un numéro unique, son adresse.

4 / 21
Une question d’adresse
4

Figure : Le vrai visage de la mémoire beaucoup de cases, toutes


numérotées

- Sur le schéma, on voit cette fois toutes les cases de la mémoire


avec leurs adresses.
- Notre programme utilise une seule de ces cases, la 53768, pour y
stocker sa variable.
5 / 21
Une question d’adresse
5

Le point important ici est que chaque variable possède une seule
adresse et que chaque adresse correspond à une seule variable.
L’adresse est donc un deuxième moyen d’accéder à une variable. On
peut atteindre la case jaune du schéma par deux chemins
différents :
On peut passer par son nom (l’étiquette) comme on sait déjà
le faire.
Mais on peut aussi accéder à la variable grâce à son adresse
(son numéro de case).
On pourrait alors dire à l’ordinateur "Affiche moi le contenu de
l’adresse 53768" ou encore "Additionne les contenus des adresses
1267 et 91238".

6 / 21
Afficher l’adresse
1

En C++, le symbole pour obtenir l’adresse d’une variable est


l’esperluette (&).
Si je veux afficher l’adresse de la variable ageUtilisateur, je dois
donc écrire &ageUtilisateur.

7 / 21
Les pointeurs
1

Les adresses sont des nombres.


Vous connaissez plusieurs types permettant de stocker des
nombres : int, unsigned int, double.
Peut-on donc stocker une adresse dans une variable ? La
réponse est oui.
C’est possible, mais pas avec les types que vous connaissez.
Il nous faut utiliser un type un peu particulier : le pointeur.
Un pointeur est une variable qui contient l’adresse d’une autre
variable.

8 / 21
Déclarer un pointeur
1

Pour déclarer un pointeur il faut, comme pour les variables, deux


choses :
un type ;
un nom.
Pour le nom, il n’y a rien de particulier à signaler. Les mêmes règles
que pour les variables s’appliquent. Le type d’un pointeur a une
petite subtilité. Il faut indiquer quel est le type de variable dont on
veut stocker l’adresse et ajouter une étoile (*). Je crois qu’un
exemple sera plus simple.
int *pointeur ;
Ce code déclare un pointeur qui peut contenir l’adresse d’une
variable de type int.

9 / 21
Stocker une adresse
1 - Exemple

La ligne ptr = &ageUtilisateur ; est celle qui nous intéresse. Elle


écrit l’adresse de la variable ageUtilisateur dans le pointeur ptr. On
dit alors que le pointeur ptr pointe sur ageUtilisateur.

10 / 21
Stocker une adresse
2

On retrouve quelques éléments familiers : la mémoire avec sa grille


de cases et la variable ageUtilisateur dans la case n° 53768. La
nouveauté est bien sûr le pointeur. Dans la case mémoire n° 14566,
il y a une variable nommée ptr qui a pour valeur l’adresse 53768,
c’est-à-dire l’adresse de la variable ageUtilisateur.

Figure : La mémoire après la déclaration d’une variable et d’un pointeur


pointant sur cette variable 11 / 21
Afficher l’adresse
1 - Exemple

#include <iostream>
using namespace std ;
int main()
{
int ageUtilisateur(16) ;
int *ptr(0) ;
ptr = &ageUtilisateur ;
cout « "L’adresse de ’ageUtilisateur’ est : " « &ageUtilisateur «
endl ;
cout « "La valeur de pointeur est : " « ptr « endl ;
return 0 ;
}

12 / 21
Accéder à la valeur pointée
1

13 / 21
Accéder à la valeur pointée
2

En faisant cout « *ptr, le programme effectue les étapes suivantes :


1 Aller dans la case mémoire nommée ptr ;
2 Lire la valeur enregistrée ;
3 Suivre la flèche pour aller à l’adresse pointée ;
4 Lire la valeur stockée dans la case ;
5 Afficher cette valeur : ici, ce sera bien sûr 16.
En utilisant l’étoile, on accède à la valeur de la variable pointée.
C’est ce qui s’appelle déréférencer un pointeur. Voici donc un
deuxième moyen d’accéder à la valeur de ageUtilisateur.

14 / 21
L’allocation dynamique
La gestion automatique de la mémoire

Lors de la déclaration d’une variable, le programme effectue deux


étapes :
1 Il demande à l’ordinateur de lui fournir une zone dans la
mémoire. En termes techniques, on parle d’allocation de la
mémoire.
2 Il remplit cette case avec la valeur fournie. On parle alors
d’initialisation de la variable.
De même, lorsque l’on arrive à la fin d’une fonction, le programme
rend la mémoire utilisée à l’ordinateur. C’est ce qu’on appelle la
libération de la mémoire.

15 / 21
L’allocation dynamique
Allouer un espace mémoire - 1

Pour demander manuellement une case dans la mémoire, il faut


utiliser l’opérateur new.
new demande une case à l’ordinateur et renvoie un pointeur
pointant vers cette case.
int *pointeur(0) ;
pointeur = new int ;
La deuxième ligne demande une case mémoire pouvant stocker un
entier et l’adresse de cette case est stockée dans le pointeur.

16 / 21
L’allocation dynamique
Allouer un espace mémoire - 2

Figure : La mémoire après l’allocation dynamique d’un entier

17 / 21
L’allocation dynamique
Allouer un espace mémoire - 3

Figure : La mémoire après avoir alloué une variable et changé la valeur de


cette variable

18 / 21
L’allocation dynamique
Libérer la mémoire - 1

Une fois que l’on n’a plus besoin de la case mémoire, il faut la
rendre à l’ordinateur. Cela se fait via l’opérateur delete.
int *pointeur(0) ;
pointeur = new int ;
delete pointeur ; //On libère la case mémoire

La case est alors rendue à l’ordinateur qui pourra l’employer à autre


chose.

19 / 21
L’allocation dynamique
Libérer la mémoire - 2

Le pointeur, lui, existe toujours et il pointe toujours sur la case,


mais vous n’avez plus le droit de l’utiliser.

Figure : Un pointeur pointant sur une case vide après un appel à delete

20 / 21
L’allocation dynamique
Libérer la mémoire - 3

Après avoir fait appel à delete, il est donc essentiel de supprimer


cette flèche en mettant le pointeur à l’adresse 0. Ne pas le faire est
une cause très courante de plantage des programmes.

21 / 21

Vous aimerez peut-être aussi