35
22/09/16 1 MASTER EEA 2 ème année HMEE325 : Optimisation et programmation avancée Langage C/C++: gestion dynamique de la mémoire Alberto BOSIO [email protected] http://www.lirmm.fr/~bosio/HMEE325 2 Les pointeurs n Définition dun pointeur n Un pointeur est une variable contenant des adresses demplacements mémoires n On dit dun pointeur bien initialisé, quil pointe sur un emplacement mémoire int *pI1, *pI2; double *pD; n Allocation statique n Avant toute chose, un pointeur doit être initialisé int X; int *P; P = &X; // P contient ladresse de la variable X *P = 6; // Est équivalent à X = 6

Les pointeurs - lirmm.frbosio/HMEE325/02-pointers.pdf · Les pointeurs n Définition d ... Rappel sur le typage statique 1. En cas de typage statique, on affiche (1,2) ou (5,3) 2

  • Upload
    dinhthu

  • View
    218

  • Download
    0

Embed Size (px)

Citation preview

22/09/16

1

MASTER EEA 2ème année

HMEE325 : Optimisation et

programmation avancée Langage C/C++: gestion dynamique de la mémoire

Alberto BOSIO [email protected]

http://www.lirmm.fr/~bosio/HMEE325

2

Les pointeurs n  Définition d’un pointeur

n  Un pointeur est une variable contenant des adresses d’emplacements mémoires

n  On dit d’un pointeur bien initialisé, qu’il pointe sur un emplacement mémoire int *pI1, *pI2; double *pD;

n  Allocation statique n  Avant toute chose, un pointeur doit être initialisé int X; int *P; P = &X; // P contient l’adresse de la variable X *P = 6; // Est équivalent à X = 6

22/09/16

2

3

Allocation dynamique

n  En langage C++ n  L’opérateur « new <Type> » permet de

réserver un emplacement mémoire pouvant contenir un objet de type Type

n  Si possible, l’opérateur « new <Type> » retourne l’adresse de l’emplacement réservé

n  Si la mémoire est saturée, l’opérateur « new <Type> » retourne la valeur nulle

n  L’opérateur « delete » permet de libérer un espace mémoire réservé

4

Exemple // On place dans P l’adresse d’un emplacement

mémoire pouvant contenir un entier int *P; // déclaration P = new int; // allocation if (P == NULL) cerr << Memory Allocation Error << endl;

else { // On place l’entier 5 dans l’emplacement pointé par P *P = 5; // On libère l’emplacement pointé par P // grâce à l’opérateur delete

delete P; }

22/09/16

3

5

Manipulations de base

int *P, *Q; // Déclaration de deux pointeurs

int X; // Déclaration d’une variable standard

6

Manipulations de base

P = &X; // Allocation statique

*P = 6; // Affectation indirecte de X cout << X; // Affiche 6

22/09/16

4

7

Manipulations de base P = new int; // Allocation dynamique

*P = 7; // Initialisation de l’emplacement // pointé par P cout << *P; // Affiche 7

8

Manipulations de base

Q = P; // Copie du contenu d’un pointeur

22/09/16

5

9

Manipulations de base Q = P; // Copie du contenu d’un pointeur Q = new int; // Allocation statique *Q = *P + 1; // Initialisation de l’emplacement

// pointé par Q P = 0; // Emplacement pointé par P perdu delete Q; // Libération correcte Q = 0; // Affectation non automatique

10

Manipulations de base

Q = new int; // Allocation statique

*Q = *P + 1; // Initialisation de l’emplacement

22/09/16

6

11

Manipulations de base

P = NULL; // Emplacement pointé par P perdu

delete Q; // Libération correcte Q = NULL; // Affectation non automatique

12

Problème de gestion mémoire int *P, *Q; // Déclaration de deux pointeurs P = new int; // Allocation dynamique *P = 1; Q = P; // Copie de pointeur *Q = *Q + 2; // Modification de l’emplacement // pointé par P et Q

22/09/16

7

13

Problème de gestion mémoire delete P; // Libération de l’emplacement P = NULL; // pointé par P -> et Q // DANGER - DANGER - DANGER // Q pointe sur un emplacement non réservé

14

Allocation dynamique de tableaux

const int N = 4; // Déclaration statique double T[N];

for(int i=0; i<N; i++) //Initialisation du tableau

T[i] = 2*i;

22/09/16

8

15

Allocation dynamique de tableaux

const int N = 4; // Déclaration statique double T[N]; for(int i=0; i<N; i++) //Initialisation du tableau

T[i] = 2*i;

La taille du tableaux doit être constant

16

Allocation dynamique de tableaux int N; cout << "Insert the size : "; cin >> N; double T[N];

for(int i=0; i<N; i++) //Initialisation du tableau

T[i] = 2*i;

22/09/16

9

17

Allocation dynamique de tableaux int N; cout << "Insert the size : "; cin >> N; double T[N];

for(int i=0; i<N; i++) //Initialisation du tableau

T[i] = 2*i;

18

Allocation dynamique de tableaux int N; double *pT; // pointeur

cout << "Insert the size : "; cin >> N;

pT = new double[N]; // allocation dyunamique

22/09/16

10

19

Allocation dynamique de tableaux int N; double *pT; // pointeur

cout << "Insert the size : "; cin >> N;

pT = new double[N]; // allocation dynamique

Dans ce cas N = 3

20

Allocation dynamique de tableaux for(int i=0; i<N; i++) //Utilisation du tableau

pT[i] = T[i] + 1;

22/09/16

11

21

Allocation dynamique de tableaux

delete [] pT; // Libération du tableau

pT = NULL;

22

Allocation dynamique de tableaux

pT = T; // pT pointe sur T for(int i=0; i<N; i++)

pT[i] = T[i] + 2;

// T[i] = T[i] + 2;

22/09/16

12

23

Allocation dynamique de structures struct Point { // Modèle de structure int x; int y; }; Point A; A.x = 3; A.y = 5; Point *pA; // Déclaration d’un pointeur pA = new Point; // Allocation dynamique pA->x = 7; pA->y = 3;

24

Allocation dynamique de structures struct Point { // Modèle de structure int x; int y; }; Point A; A.x = 3; A.y = 5; Point *pA; // Déclaration d’un pointeur pA = new Point; // Allocation dynamique pA->x = 7; pA->y = 3;

Operatuer « -> »

Équivalent a l’operatuer « * »

(*pA).x = 7; (*pA).y = 3;

22/09/16

13

25

Allocation dynamique de structures

Point *pB; // Copie de pointeur pB = pA;

pB->y = pB->x + 1;

26

Allocation dynamique de structures

pA = &A; // Affectation statique

pA->x = 1; (*pA).y = A.y - 1;

22/09/16

14

27

Allocation dynamique de structures

delete pA; // Libération de mémoire

pA = pB = 0;

28

Modes de transmission des arguments n  Par référence

void echanger(int& a, int& b){ int tmp = a; a = b; b = tmp; }

n  Par adresses void echanger(int* pa, int* pb) { int tmp = *pa; *pa = *pb; *pb = tmp; }

22/09/16

15

29

Modes de transmission des arguments n  Par référence

void echanger(int& a, int& b){ int tmp = a; a = b; b = tmp; }

n  Par adresses void echanger(int* pa, int* pb) { int tmp = *pa; *pa = *pb; *pb = tmp; }

Le mode de transmission par

référence « spécifique au C++ » cache certaines difficultés de manipulation des pointeurs

30

Modes de transmission des arguments n  Transmission équivalente de structures

n  Par référence void symetrique(Point& a) { a.x = -a.x; a.y = -a.y; } n  Par adresses void symetrique(Point* pa) { pa->x = -pa->x; // (*pa).x = -(*pa).x pa->y = -pa->y; // (*pa).y = -(*pa).y }

22/09/16

16

31

Modes de transmission des arguments n  Transmission de tableaux

n  Toujours par adresses, le nom d’un tableau représentant : n  son adresse mémoire n  l’adresse de son premier élément

void initialiser(int *pT, int n) { for(int i = 0; i < n; i++) pT[i] = i; } void main() { int x[3]; initialiser(x, 3); // pT = x = &x[0] }

32

Allocation dynamique de mémoire

n  Langage C versus C++ n  La fonction « sizeof » retourne la taille de l’espace mémoire occupé par une

variable de type donné n  La fonction « malloc » doit être utilisée à la place de l’opérateur « new »

int n; cout << sizeof(n) << sizeof(int); int *pI, *pV; Point *pT, *pR; pI = new int; // pI = (int*) malloc(sizeof(int)); pV = new int[10]; // pV = (int*) malloc(sizeof(int)*10); pT = new Point; // pT = (Point*) malloc(sizeof(Point)); pR = new Point[2];// pR = (Point*) malloc(sizeof(Point)*2);

C++ C

22/09/16

17

33

Allocation dynamique de mémoire

n  Langage C versus C++ n  La fonction « free » doit être utilisée à la place de

l’opérateur « delete » pI = new int; delete pI; pI = (int*) malloc(sizeof(int));free(pI);

n  Les fonctions « free » et « malloc » doivent être utilisées de pair de même que les opérateurs « new » et « delete »

34

Conversion de types

n  Classe de base class Point {

private:int mx;int my;

public:Point (int x, int y);~Point ();

void afficher ();

};

n  Classe dérivée class PointCol : public Point {private:

char m_couleur[51];

public:PointCol (int x, int y, char *col);

~PointCol ();

void afficher ();

};

22/09/16

18

35

Conversion de types

36

Conversion de types

Un objet d’une classe dérivée peut toujours être converti en un objet de la classe de base correspondante, mais pas l’inverse

22/09/16

19

37

Rappel sur le typage statique

n  Classe de base class Point {

private:int mx;int my;

public:Point (int x, int y);~Point ();

void afficher ();

};

n  Classe dérivée class PointCol : public Point {private:

char m_couleur[51];

public:PointCol (int x, int y, char *col);

~PointCol ();

void afficher ();

};

38

Rappel sur le typage statique

22/09/16

20

39

Rappel sur le typage statique

1. En cas de typage statique, on affiche (1,2) ou (5,3)

2. La fonction Point::afficher est toujours appelée car ad est de type Point*

3. Le choix de la fonction afficher à appeler est fait à la compilation

40

Mise en œuvre du typage dynamique - Polymorphisme

n  Classe de base class Point {

private:int mx;int my;

public:Point (int x, int y);~Point ();

virtual void afficher ();

};

n  Classe dérivée class PointCol : public Point {private:

char m_couleur[51];

public:PointCol (int x, int y, char *col);

~PointCol ();

virtual void afficher ();

};

22/09/16

21

41

Mise en œuvre du typage dynamique

1. En cas de typage dynamique, on affiche (1,2) ou (5,3)-Noir

2. Le choix de la fonction afficher à appeler est fait à l’exécution en fonction du type de l’objet pointé par ad (non du type du pointeur ad)

How virtual functions are (typically) implemented n  If a class has any virtual functions, an extra (hidden) pointer is

added to the beginning of each object of that class. This pointer points to the virtual function table (v-table for short), which pointers to code for each virtual function supported by the object.

vtable ptr

...

data

data

ptr to code

ptr to code

...

object vtable 01001 01011 11010 01001

01001 01011 11010 01001

22/09/16

22

How virtual functions are (typically) implemented n  Example:

class Shape { int xCoord, yCoord; // coordinates of center ShapeColor color; // current color public: void move(int xNew, int yNew); virtual void draw(); virtual void rotate(double angle); virtual double area(); }; Shape s1;

The object s1 looks like:

vtable ptr

color

xCoord

yCoord

ptr to Shape::draw

ptr to Shape::rotate

ptr to Shape::area

s1

Shape v-table

How virtual functions are (typically) implemented n  Multiple object of type Shape share the same v-table:

n  Shape s1; n  Shape s2;

22/09/16

23

How virtual functions are (typically) implemented

vtable ptr

color

xCoord

yCoord

s2

vtable ptr

color

xCoord

yCoord

s1 ptr to Shape::draw

ptr to Shape::rotate

ptr to Shape::area

Shape v-table

How virtual functions are (typically) implemented n  Each class derived from Shape gets its own v-table, which contains

code for inherited and overridden member functions. Suppose Circle inherits Shape::rotate (without overriding it), and overrides Shape::draw and Shape::area.

n  To make things interesting, let’s also suppose that Circle adds a new virtual function, circumference.

class Circle: public Shape { int radius; public: void draw(); double area(); virtual double circumference(); };

22/09/16

24

How virtual functions are (typically) implemented

n  Shape s1; n  Shape s2; n  Circle c1;

n  Now the objects and v-tables look like:

s2

vtable ptr

color

xCoord

yCoord

s1

ptr to Circle::draw

ptr to Shape::rotate

ptr to Circle::area

Circle v-table

ptr to Shape::draw

ptr to Shape::rotate

ptr to Shape::area

Shape v-table

ptr to Circle::circ...

vtable ptr

color

xCoord

yCoord

vtable ptr

color

xCoord

yCoord

radius

c1

22/09/16

25

How virtual functions are (typically) implemented n  When a virtual function is invoked, C++ looks up the right code at run-

time (it knows at compile-time what offset in the v-table to look in) and calls it:

n  Shape *sPtr = new Circle(); n  double a = sPtr->area();

sPtr

ptr to Circle::draw

ptr to Shape::rotate

ptr to Circle::area

ptr to Circle::circ...

vtable ptr

color

xCoord

yCoord

radius

Polymorphisme

n  Le mot polymorphisme est formé à partir du grec ancien (polloi) qui signifie « plusieurs » (morphos) qui signifie « forme »

50

22/09/16

26

Abstraction des données

n  On veut modéliser d’autres formes géométriques dans le même programme : n  Triangle n  Cercle n  ….

51

Abstraction des données

n  Définir une nouvelle classe à partir de classes déjà existantes

n  Par dérivation n  Héritage simple : à partir d’une classe n  Héritage multiple : à partir de plusieurs

classes

52

22/09/16

27

53

Abstraction des données

n  Intérêts de l’héritage n  Définir de nouveaux attributs et de

nouvelles méthodes pour la classe dérivée, qui viennent s’ajouter à ceux et celles héritées

n  Créer une hiérarchie de classes de plus en plus spécialisées (ne pas repartir de zéro)

n  Utiliser des librairies de classes existantes

54

Exemple

n  Définition des classes «Triangle », « Cercle », «Rectangle» à partir d’une classe «Forme». Un triangle, cercle ou rectangle étant un exemple de forme géométrique

22/09/16

28

55

Exemple

Exemple

56

// class de base

class forme {

/* interface */public:

forme () ;virtual ~forme ();

virtual int surface ( ) = 0; virtual int perimetre ( ) = 0;

};

// implementation

forme::forme () {cout << " form constructor " << endl;

}

forme::~forme () {cout << " form destructor " << endl;

}

22/09/16

29

Exemple

57

// class de base

class forme {

/* interface */public:

forme () ;virtual ~forme ();

virtual int surface ( ) = 0; virtual int perimetre ( ) = 0;

};

Fonction virtuelle

Exemple

58

// class de base

class forme {

/* interface */public:

forme () ;virtual ~forme ();

virtual int surface ( ) = 0; virtual int perimetre ( ) = 0;

};

Fonction virtuelle pure

22/09/16

30

Définition

59

n  Une classe est dite classe abstraite si elle a au moins une fonction virtuelle pure.

n  On ne peut pas instancier un objet à partir d’une classe abstraite : n  forme l_forme;

Définition

60

n  Une classe est dit classe abstrait si elle as au moins une fonction virtuelle pure.

n  On peux pas instancier un objet a partir d’une classe abstrait: n  forme obj_forme;

main.cpp:24: error: cannot declare variable 'l_forme' to be of abstract type 'forme' forme.h:20: note: because the following virtual functions are pure within 'forme': forme.h:29: note: virtual int forme::surface() forme.h:30: note: virtual int forme::perimetre()

22/09/16

31

Exemple

61

// classe dérivée

class cercle : public forme {

private:int r;

public:cercle ();virtual ~cercle ();void set_r (int pr);

virtual int surface ();virtual int perimetre ();

};

62

L’héritage simple

n  Les membres publics de la classe base sont des membres publics dérivés

n  Une classe dérivée n’a jamais accès aux membres privés de la classe base

22/09/16

32

Exemple

63

// implementation

cercle::cercle () {cout << " cercle constructor " << endl;r = 0;

}

cercle::~cercle () {cout << " cercle destructor " << endl;

}

Exemple

64

// implementation

void cercle::set_r (int pr) {if (pr >= 0)

r = pr;else

r = 0;}int cercle::surface () {

cout << " cercle surface " << endl;return ( 2 * 3.14 * r);

}int cercle::perimetre () {

cout << " cercle perimetre " << endl;return ( 3.14 * r *r );

}

22/09/16

33

Exemple

65

// main

int main (void) {cercle l_cercle; // objet definition

l_cercle.set_r (2);

cout << “ surface = “ << l_cercle.surface () << endl;

return 0; // end }

Exemple

66

n  Déterminer les résultats en sortie de l’exemple précédent.

22/09/16

34

Exercise

67

nombre

entiers naturels

entiers relatifs rationnels réel

interafce: •  set_value •  get_value •  print_number

Inheritance

Class D: private B { … };Class D: protected B { … };Class D: public B { … };

68

22/09/16

35

Inheritance

n  If B is a private base: n  Its public and protected members can be

used only by D n  Only members of D can convert D* in to B*

n  If B is a protected base: n  Its public and protected members can be

used only by D and any class derived from D n  Only members of D or derived from D can

convert D* in to B*

69