9 memoire support
TRANSCRIPT
-
7/25/2019 9 Memoire Support
1/115
Allocation dynamique de tableaux et de structures
-
7/25/2019 9 Memoire Support
2/115
Mmoire
La mmoire d'un ordinateur est compose d'un grand nombre d'octets(une valeurentre 0 et 255) :
Chaque octet est repr par une adresse, qui est un nombre entier.
adresse octet
0
1
23
!
2
-
7/25/2019 9 Memoire Support
3/115
Les variables sont stockes en mmoire. Par exemple:
int a(3);
adresse contenu
24996
25000
25004 ?
25008 ?
25012 ?
25016 ?
25020
a3
-
7/25/2019 9 Memoire Support
4/115
On peut obtenir l'adresse d'une variable grce l'oprateur &:
Par exemple:
int a(3);
cout
-
7/25/2019 9 Memoire Support
5/115
En C et en C++, on peut dfinir des variables pour qu'elles contiennentdes adresses.
Pour dclarer une telle variable, Il faut ajouter une toile *entre le type
et le nom de la variable:
int *p;
pest appel unpointeur.
Stocker une adresse dans une variable
-
7/25/2019 9 Memoire Support
6/115
Si on fait:
int * p;
p = &a;
pcontient l'adresse de a.
Stocker une adresse dans une variable
adresse contenu
24996
25000
25004 ?
25008
25012
25016
25108
a
p
3
?
25004
-
7/25/2019 9 Memoire Support
7/115
pcontient l'adresse de a.
On dit que ppointe sur a.
La valeur de l'adresse de a n'est pasimportante en elle-mme, ce qui est
important est que ppointe sur a.
Ceci est souvent reprsent par une flcheallant de p a.
Reprsentation graphique (1)
adresse contenu
24996
25000
25004 ?
25008
25012
25016
25108
a
p
3
-
7/25/2019 9 Memoire Support
8/115
On n'a gnralement pas besoin de la reprsentation de la mmoire, et
on peut ne garder que la reprsentation des variables.
int a(3);
int * p;
p = &a;
Reprsentation graphique (2)
a
p
3
-
7/25/2019 9 Memoire Support
9/115
L'oprateur *permet d'accder la valeur stocke une adresse:
cout
-
7/25/2019 9 Memoire Support
10/115
On peut aussi utiliser l'oprateur pour modifier une valeur pointe parun pointeur:
int a(3);
int * p;
p = &a;
*p = 5;
Modifier la valeur pointe par un pointeur
5a
p
3
-
7/25/2019 9 Memoire Support
11/115
l'toile utilise pour dclarer un pointeur:
int * p;
et l'toile pour obtenir la valeur pointe par le pointeur:
*p = 5;
Attention ne pas confondre
Mme symbole (*) maissignification diffrente.
-
7/25/2019 9 Memoire Support
12/115
Rsum
Un pointeur est une variable. On dclare un pointeur en mettant une
toile (*) entre le type et le nom du pointeur:
int * p;
Un pointeur contient une adresse.
On peut obtenir l'adresse d'une variable avec l'oprateur &:
int a = 0;
p = &a;
L'oprateur *permet d'accder la mmoire pointe par un pointeur:
int b = *p;
*p = 1;
a
p
0
b
0
1
-
7/25/2019 9 Memoire Support
13/115
Dclaration d'un pointeur
Un pointeur est une variable:On peut dclarer plusieurs pointeurs sur une mme ligne, et initialiser
un pointeur lors de sa dclaration. Exemples:
double a;
double * p1(&a);
int * p2, * p3;
Attention: pour dclarer plusieurs pointeurs sur une mme ligne, ilfaut rpterl'toile. Si on fait:
int * p2, p3; // !!
p2est de type pointeur sur int, mais p3est une variable classique,de type int.
-
7/25/2019 9 Memoire Support
14/115
Le pointeur NULLou 0
On utilise parfois la valeur 0, ou la constante NULL(de type pointeur, qui vaut
0) pour initialiser un pointeur:int * p = 0;
ou
int * p = NULL;
L'adresse 0n'est jamais utilise pour stocker des variables, elle correspond
donc toujours une adresse invalide: Si on essaie d'accder la valeurpointe par pen faisant par exemple:
int * p = 0;
int a = *p;
*p = 12;
on provoque un:
Segmentation fault
L'intrt du pointeur NULL est par exemple de signaler qu'une fonction n'a
pas pu fonctionner correctement, ou qu'un pointeur ne contient pas une
adresse valide.
-
7/25/2019 9 Memoire Support
15/115
On peut voir l'oprateur *comme l'inverse de l'oprateur &:
b = *(&a);
est quivalent
b = a;
On peut mettre zro, un ou plusieurs espaces avant et aprs l'toile et
le et commercial:
int *pa = & a;
b = * pa;
Remarques
-
7/25/2019 9 Memoire Support
16/115
-
7/25/2019 9 Memoire Support
17/115
int n(1), p(2);int * ad1, * ad2;
ad1 = &n;
ad2 = &p;
*ad1 = *ad2 + 3;ad1 = ad2;
*ad1 = *ad2 + 5;
Pas--pas
ad2ad1
n p
1 2
-
7/25/2019 9 Memoire Support
18/115
int n(1), p(2);int * ad1, * ad2;
ad1 = &n;
ad2 = &p;
*ad1 = *ad2 + 3;ad1 = ad2;
*ad1 = *ad2 + 5;
Pas--pas
ad2ad1
n p
1 2
ad1pointe sur n
-
7/25/2019 9 Memoire Support
19/115
int n(1), p(2);int * ad1, * ad2;
ad1 = &n;
ad2 = &p;
*ad1 = *ad2 + 3;ad1 = ad2;
*ad1 = *ad2 + 5;
Pas--pas
ad2ad1
n p
1 2
ad2pointe sur p
-
7/25/2019 9 Memoire Support
20/115
int n(1), p(2);int * ad1, * ad2;
ad1 = &n;
ad2 = &p;
*ad1 = *ad2 + 3;ad1 = ad2;
*ad1 = *ad2 + 5;
Pas--pas
ad2ad1
n p
1 2
exactement comme n = p + 3;ncontient maintenant 5
5
-
7/25/2019 9 Memoire Support
21/115
int n(1), p(2);int * ad1, * ad2;
ad1 = &n;
ad2 = &p;
*ad1 = *ad2 + 3;ad1 = ad2;
*ad1 = *ad2 + 5;
Pas--pas
ad2ad1
n p25
-
7/25/2019 9 Memoire Support
22/115
int n(1), p(2);int * ad1, * ad2;
ad1 = &n;
ad2 = &p;
*ad1 = *ad2 + 3;ad1 = ad2;
*ad1 = *ad2 + 5;
Pas--pas
ad2ad1
n p2
ad1et ad2pointent maintenant tous lesdeux sur p.
5
-
7/25/2019 9 Memoire Support
23/115
int n(1), p(2);int * ad1, * ad2;
ad1 = &n;
ad2 = &p;
*ad1 = *ad2 + 3;ad1 = ad2;
*ad1 = *ad2 + 5;
Pas--pas
ad2ad1
n p2
exactement comme p = p + 5;
pcontient donc maintenant 7
5
-
7/25/2019 9 Memoire Support
24/115
Exerciceint a(2), b(5);
int * p;
p = &a;
cout
-
7/25/2019 9 Memoire Support
25/115
Pointeur en paramtre d'une fonction
-
7/25/2019 9 Memoire Support
26/115
Rappel
Si on excute:
void mis_a_zero(int a){
a = 0;}
int main(){
int n = 10;
mis_a_zero(n);
cout
-
7/25/2019 9 Memoire Support
27/115
Pas--pas
void mis_a_zero(int a){a = 0;
}
int main(){int n = 10;
cout
-
7/25/2019 9 Memoire Support
28/115
Pas--pas
void mis_a_zero(int a){a = 0;
}
int main(){int n = 10;
cout
-
7/25/2019 9 Memoire Support
29/115
Pas--pas
void mis_a_zero(int a){a = 0;
}
int main(){int n = 10;
cout
-
7/25/2019 9 Memoire Support
30/115
Pas--pas
void mis_a_zero(int a){a = 0;
}
int main(){int n = 10;
cout
-
7/25/2019 9 Memoire Support
31/115
Pas--pas
void mis_a_zero(int a){a = 0;
}
int main(){int n = 10;
cout
-
7/25/2019 9 Memoire Support
32/115
Pour que la fonction puisse modifier la variable n, il y a deux options en
C++:
soit utiliser un passage par rfrence,
soit utiliser un pointeur.
Nous avons dj vu le passage par rfrence. Nous allons voir la
solution avec un pointeur.
Une fonction modifiantune variable passe en paramtre
-
7/25/2019 9 Memoire Support
33/115
Pour que la fonction puisse modifier la variable n, il faut passer enparamtre l'adresse de la variable plutt que sa valeur:
void mis_a_zero(int* pa){*pa = 0;
}
int main(){int n = 10;
mis_a_zero(&n);
cout
-
7/25/2019 9 Memoire Support
34/115
void mis_a_zero(int * pa){*pa = 0;
}
int main(){int n = 10;
mis_a_zero(&n);
cout
-
7/25/2019 9 Memoire Support
35/115
void mis_a_zero(int * pa){*pa = 0;
}
int main(){int n = 10;
mis_a_zero(&n);
cout
-
7/25/2019 9 Memoire Support
36/115
void mis_a_zero(int * pa){*pa = 0;
}
int main(){int n = 10;
mis_a_zero(&n);
cout
-
7/25/2019 9 Memoire Support
37/115
void mis_a_zero(int * pa){*pa = 0;
}
int main(){int n = 10;
mis_a_zero(&n);
cout
-
7/25/2019 9 Memoire Support
38/115
void mis_a_zero(int * pa){*pa = 0;
}
int main(){int n = 10;
mis_a_zero(&n);
cout
-
7/25/2019 9 Memoire Support
39/115
void mis_a_zero(int * pa){*pa = 0;
}
int main(){int n = 10;
mis_a_zero(&n);
cout
-
7/25/2019 9 Memoire Support
40/115
void f(int * p, int q)
{*p = *p + q;}
void g(int * r){f(r, 1);
}
int a = 0, b = 2;f(&a, b);cout
-
7/25/2019 9 Memoire Support
41/115
Une fonction peut modifierles lments d'un tableau
pass en paramtre
-
7/25/2019 9 Memoire Support
42/115
Utilis seul, le nom du tableau correspond l'adresse du premierlment.
Par exemple, on peut faire:
int T[5];
int * tab = T;
et tabpointe alors sur le premier lment de T.
Attention, Tn'est pas pour autant un pointeur.
On ne peut pas faire par exemple:T = &a;
si Ta t dclar comme un tableau.
Tableaux et pointeurs
adresse contenu
19996
T= 20000 T[0]
20004 T[1]
20008 T[2]
20012 T[3]
20016 T[4]
20020
tab
-
7/25/2019 9 Memoire Support
43/115
Aprs:
int T[5];int * tab = T;
tabpointe sur le premier lment de T.
*tabcorrespond donc T[0], le premier lment de T.
tab + 1est l'adresse du deuxime lment de T.
*(tab + 1) correspond donc T[1], le deuximelment de T.
etc...
Tableaux et pointeurs
adresse contenu
19996
T= 20000 T[0]
20004 T[1]
20008 T[2]
20012 T[3]
20016 T[4]
20020
tab
-
7/25/2019 9 Memoire Support
44/115
Notez que:
Si
tabvaut 20000,
et si tabest un pointeur sur int
Alors
tab + 1vaut 20004
pour pointer sur le int suivant: un int est reprsent sur 4 octets, et les adressessont dfinies en octet.
Ce mcanisme de calcul simplifie l'accs aux lments du tableau: il n'y a pas savoirqu'il faut multiplier par 4 dans le cas des int, par 8 dans le cas des double, etc...
-
7/25/2019 9 Memoire Support
45/115
Aprs:
int T[5];int * tab = T;
tabpointe sur le premier lment de T.
*tabcorrespond donc T[0], le premier lment de T.
tab + 1est l'adresse du deuxime lment de T.
*(tab + 1)correspond donc T[1], le deuxime lment de T.
On peut galement crire tab[1] la place de *(tab + 1).
Tableaux et pointeurs
adresse contenu
19996
T= 20000 T[0]
20004 T[1]
20008 T[2]
20012 T[3]
20016 T[4]20020
tab
-
7/25/2019 9 Memoire Support
46/115
En C et en C++, on peut crire
tab[i]
la place de
*(tab + i)
ce qui permet d'utiliser tab comme on utiliserait un
tableau!
-
7/25/2019 9 Memoire Support
47/115
int T[10];
for(int i = 0; i < 10; i++)
T[i] = i * i;
int * p = T, * q = &(T[2]);
cout
-
7/25/2019 9 Memoire Support
48/115
Supposons qu'on veut crire une fonction qui ajoute 1 aux lments d'un
tableau. On peut donc crire cette fonction comme a:
void ajoute1_aux_elements(int * tab){
for(int i(0); i < 5; ++i) {*(tab + i) = *(tab + i) + 1;
}}
ou comme a:
void ajoute1_aux_elements(int * tab){for(int i(0); i < 5; ++i) {
tab[i]= tab[i] + 1;}
}
et on peut appeler cette fonction ainsi:
int T[5];ajoute1_aux_elements(T);
Accs aux lments d'un tableau
adresse contenu
19996
T= 20000 T[0]
20004 T[1]
20008 T[2]
20012 T[3]
20016 T[4]
20020
tab
-
7/25/2019 9 Memoire Support
49/115
void ajoute1_aux_elements(int * tab){for(int i(0); i < 5; ++i) {tab[i]= tab[i] + 1;
}}
...
int T[5];
ajoute1_aux_elements(T);
adresse contenu
19996
T= 20000 T[0]
20004 T[1]
20008 T[2]
20012 T[3]
20016 T[4]
20020
-
7/25/2019 9 Memoire Support
50/115
void ajoute1_aux_elements(int * tab){for(int i(0); i < 5; ++i) {tab[i]= tab[i] + 1;
}}
...
int T[5];
ajoute1_aux_elements(T);
adresse contenu
19996
T= 20000 T[0]
20004 T[1]
20008 T[2]
20012 T[3]
20016 T[4]
20020
tab
-
7/25/2019 9 Memoire Support
51/115
void ajoute1_aux_elements(int * tab){for(int i(0); i < 5; ++i) {tab[i]= tab[i] + 1;
}}
...
int T[5];
ajoute1_aux_elements(T);
adresse contenu
19996
T= 20000 T[0]
20004 T[1]
20008 T[2]
20012 T[3]20016 T[4]
20020
tab
i
-
7/25/2019 9 Memoire Support
52/115
void ajoute1_aux_elements(int * tab){for(int i(0); i < 5; ++i) {tab[i]= tab[i] + 1;
}}
...
int T[5];
ajoute1_aux_elements(T);
adresse contenu
19996
T= 20000 T[0]
20004 T[1]
20008 T[2]
20012 T[3]20016 T[4]
20020
tab
-
7/25/2019 9 Memoire Support
53/115
void ajoute1_aux_elements(int * tab){for(int i(0); i < 5; ++i) {tab[i]= tab[i] + 1;
}}
...
int T[5];
ajoute1_aux_elements(T);
adresse contenu
19996
T= 20000 T[0]
20004 T[1]
20008 T[2]
20012 T[3]20016 T[4]
20020
tab
-
7/25/2019 9 Memoire Support
54/115
On peut crire indiffremment:
void ajoute1_aux_elements(int tab[5])
ou
void ajoute1_aux_elements(int * tab)
Le 5du premier en-tte N'est PAS considr par le compilateur.
On peut mme crire:
void ajoute1_aux_elements(int tab[])
-
7/25/2019 9 Memoire Support
55/115
On peut crire indiffremment:
void ajoute1_aux_elements(int tab[5])
ou
void ajoute1_aux_elements(int * tab)
Le 5du premier en-tte N'est PAS considr par le compilateur.
On peut mme crire:
void ajoute1_aux_elements(int tab[])
Utilisez cette notation
-
7/25/2019 9 Memoire Support
56/115
Attention au nombre d'lments
La fonction
void ajoute1_aux_elements(int * tab)
ne connat PAS LA TAILLE du tableau pass en paramtre.
-
7/25/2019 9 Memoire Support
57/115
Passer le nombre d'lments en paramtre
Pour que la fonction puisse tre utilise pour n'importe quel tableau, quelle
que soit sa taille, on peut passer la taille du tableau en paramtre.
Exemple:
void ajoute1_aux_elements(int * tab, int nb_elements)
{
for(int i(0); i
-
7/25/2019 9 Memoire Support
58/115
Exercicevoid f(int * q, int r){q = q + r;*q = 0;
}
void g(int * q, int r){q[r] = 0;
}
...
int T[4] = {1, 5, 6, 9};int * p = T;
*p = *p + 1;cout
-
7/25/2019 9 Memoire Support
59/115
Allocation dynamique:
Allouer de la mmoire
pendant l'excution du programme
-
7/25/2019 9 Memoire Support
60/115
On peut allouer de la mmoire pendant l'excution du programme.
On parle d'Allocation dynamique.
L'allocation se fait avec l'instruction new.
Une fois que la mmoire alloue n'est plus utile, IL FAUT la librer,
avec l'instruction delete.
Allouer de la mmoire
pendant l'excution du programme
-
7/25/2019 9 Memoire Support
61/115
int * tab;
tab = new int[5];
L'instruction newfait 2 choses:
1.
Elle alloue de la mmoire, c'est--dire qu'ellerserve une partie de la mmoire de l'ordinateurpour que le programme puisse l'utiliser.
Allouer de la mmoirependant l'excution du programme
mmoire
tab
-
7/25/2019 9 Memoire Support
62/115
int * tab;
tab = new int[5];
L'instruction newfait 2 choses:
1.
Elle alloue de la mmoire, c'est--dire qu'ellerserve une partie de la mmoire de l'ordinateurpour que le programme puisse l'utiliser.
2. Elle renvoie l'adresse du dbut de cettemmoire.
Dans notre exemple, tabva donc pointer sur
cette mmoire, et permettre au programme del'utiliser.
Allouer de la mmoirependant l'excution du programme
mmoire
tab
-
7/25/2019 9 Memoire Support
63/115
int * tab;
tab = new int[5];
tab[2] = 10;tab[3] = 5 * tab[2];
delete [] tab;
L'instruction deletelibre la mmoire alloue
par new, c'est--dire que cette partie de lammoire va pouvoir tre utilise par d'autres
programmes.
Le programme n'a plus le droit d'accder
cette partie de la mmoire.
Allouer de la mmoirependant l'excution du programme
mmoire
tab
-
7/25/2019 9 Memoire Support
64/115
Allocation de la mmoire:
tab = new int [5];
Libration de la mmoire:
delete [] tab;
newet delete
-
7/25/2019 9 Memoire Support
65/115
Allocation de la mmoire:
tab = new int [5];
Libration de la mmoire:
delete [] tab;
newet delete
Nombre d'lments allouer
Retourne l'adresse dupremier lment allou:
Tdoit tre dclarcomme un pointeur sur
int.
Attention ne pasoublier les crochets [ ]
Adresse de dbut dela mmoire librer
Type des lments
-
7/25/2019 9 Memoire Support
66/115
void set(int * tab, int nb_elements, int v){for(int i(0); i < nb_elements; ++i) {tab[i] = v;
}}
int main()
{int * T;int n;
cout n;
T = new int[n];
// On met tous les elements de T a 0
set(T, n, 0);
//..
// il ne faut pas oublier de liberer la memoire allouee pour T
delete [] T;
return 0;}
-
7/25/2019 9 Memoire Support
67/115
Fonction qui alloue un tableau
int * cree_tableau(int nb_elements){int * T;
T = new int[nb_elements];return T;}
Le rsultat de la fonction est un pointeur sur le premierlment du tableau.
Exemple d'utilisation:int * T = cree_tableau(10);
-
7/25/2019 9 Memoire Support
68/115
Fonction qui alloue un tableau
int * cree_tableau(int nb_elements){int * T;
T = new int[nb_elements];return T;}
Le rsultat de la fonction est un pointeur sur le premierlment du tableau.
Exemple d'utilisation:int * T = cree_tableau(10);
le rsultat de la fonction est
de type pointeur sur int
la fonction renvoie l'adresse dupremier lment du tableau
-
7/25/2019 9 Memoire Support
69/115
On peut aussi crire cree_tableaude faon plus directe:
int * cree_tableau(int nb_elements){return new int[nb_elements];
}
L t d l f ti t h t
-
7/25/2019 9 Memoire Support
70/115
Le type de la fonction est cohrent
avec le type de son rsultat
int * cree_tableau(int nb_elements){int * T;T = new int[nb_elements];return T;
}
int * cree_tableau(int nb_elements){return new int[nb_elements];
}
Test un pointeur sur int
L'expressionnew int[nb_elements]est
un pointeur sur int
-
7/25/2019 9 Memoire Support
71/115
Autre fonction qui alloue un tableau
Fonction qui alloue et remplit un tableau avec des valeurs alatoires:
int * cree_tableau_aleatoire(int nb_elements, int val_max){int * resultat = new int[nb_elements];
for(int i(0); i < nb_elements; ++i) {resultat[i] = rand() % val_max;
}
return resultat;}
Exemple d'utilisation:int * T = cree_tableau_aleatoire(5, 100);
-
7/25/2019 9 Memoire Support
72/115
int * cree_tableau_aleatoire(int nb_elements, int val_max){int * resultat = new int[nb_elements];
for(int i(0); i < nb_elements; ++i) {resultat[i] = rand() % val_max;
}
return resultat;}
int * T = cree_tableau_aleatoire(5, 100);
-
7/25/2019 9 Memoire Support
73/115
int * cree_tableau_aleatoire(int nb_elements, int val_max){int * resultat = new int[nb_elements];
for(int i(0); i < nb_elements; ++i) {resultat[i] = rand() % val_max;
}
return resultat;}
int * T = cree_tableau_aleatoire(5, 100);
5 1
-
7/25/2019 9 Memoire Support
74/115
int * cree_tableau_aleatoire(int nb_elements, int val_max){int * resultat = new int[nb_elements];
for(int i(0); i < nb_elements; ++i) {resultat[i] = rand() % val_max;
}
return resultat;}
int * T = cree_tableau_aleatoire(5, 100);
5 1
mmoire
?
?
?
??
-
7/25/2019 9 Memoire Support
75/115
int * cree_tableau_aleatoire(int nb_elements, int val_max){int * resultat = new int[nb_elements];
for(int i(0); i < nb_elements; ++i) {resultat[i] = rand() % val_max;
}
return resultat;}
int * T = cree_tableau_aleatoire(5, 100);
5 1
mmoire
?
?
?
??
resultat
-
7/25/2019 9 Memoire Support
76/115
int * cree_tableau_aleatoire(int nb_elements, int val_max){int * resultat = new int[nb_elements];
for(int i(0); i < nb_elements; ++i) {resultat[i] = rand() % val_max;
}
return resultat;}
int * T = cree_tableau_aleatoire(5, 100);
5 1
mmoire
56
34
82
1739
resultat
-
7/25/2019 9 Memoire Support
77/115
int * cree_tableau_aleatoire(int nb_elements, int val_max){int * resultat = new int[nb_elements];
for(int i(0); i < nb_elements; ++i) {resultat[i] = rand() % val_max;
}
return resultat;}
int * T = cree_tableau_aleatoire(5, 100);
5 1
mmoire
56
34
82
1739
resultat
-
7/25/2019 9 Memoire Support
78/115
int * cree_tableau_aleatoire(int nb_elements, int val_max){int * resultat = new int[nb_elements];
for(int i(0); i < nb_elements; ++i) {resultat[i] = rand() % val_max;
}
return resultat;}
int * T = cree_tableau_aleatoire(5, 100);
mmoire
56
34
82
1739
-
7/25/2019 9 Memoire Support
79/115
int * cree_tableau_aleatoire(int nb_elements, int val_max){int * resultat = new int[nb_elements];
for(int i(0); i < nb_elements; ++i) {resultat[i] = rand() % val_max;
}
return resultat;}
int * T = cree_tableau_aleatoire(5, 100);
mmoire
56
34
82
1739
resultat
-
7/25/2019 9 Memoire Support
80/115
int * cree_tableau_aleatoire(int nb_elements, int val_max){int * resultat = new int[nb_elements];
for(int i(0); i < nb_elements; ++i) {resultat[i] = rand() % val_max;
}
return resultat;}
int * T = cree_tableau_aleatoire(5, 100);
mmoire
56
34
82
1739
resultat
-
7/25/2019 9 Memoire Support
81/115
Allocation dynamique de
structures
-
7/25/2019 9 Memoire Support
82/115
struct Chat
{ string nom;double poids;
};
...
Chat * c = new Chat;
delete c;
Allocation d'une structure
c: pointeur sur Chat
alloue de la mmoire pour une
seule structure Chat
libre la mmoire pointe par c
-
7/25/2019 9 Memoire Support
83/115
struct Chat
{ string nom;double poids;
};
...
Chat * c = new Chat;
Allocation d'une structure
poids
0.0
nom
-
7/25/2019 9 Memoire Support
84/115
struct Chat
{ string nom;double poids;
};
...
Chat * c = new Chat;
Allocation d'une structure
poids
0.0
nom
c
-
7/25/2019 9 Memoire Support
85/115
struct Chat
{ string nom;double poids;
};
...
Chat * c = new Chat;
(*c).poids = 2.5;
Accder aux champs
poids
2.5
nom
c
L' t
-
7/25/2019 9 Memoire Support
86/115
La notation
(*c).poids
n'est pas trs lisible.
Il existe un oprateur, not ->(un signe moins -, un signe suprieur
>), qui permet d'crire des expressions quivalentes mais plus lisibles:
c->poids
L'oprateur ->
c->poids est quivalent (*c).poids
ou > ?
-
7/25/2019 9 Memoire Support
87/115
A gauche de.on trouve forcment une variablede type structure:Chat c;
c.poids = 2.5;
A gauche de ->on trouve forcment unpointeursur structure:
Chat * pc = &c;
pc->poids = 2.5;
.ou ->?
Messages d'erreur
-
7/25/2019 9 Memoire Support
88/115
A la compilation de:
Chat c;
c->poids = 2.5; // !!on obtient l'erreur:
error: base operand of `->' has non-pointer type `Chat'
cn'est pas un pointeur et appliquer l'oprateur ->sur cn'a donc pas de sens.
A la compilation de:
Chat * pc;pc.poids = 2.5; // !!on obtient l'erreur:
error: request for member `poids' in `pc', which is of non-classtype `Chat*'
L'oprateur. s'applique sur une structure, pas un pointeur commepcest ici.
Messages d erreur
-
7/25/2019 9 Memoire Support
89/115
Fonction qui alloue une structure
Chat * cree_chat(string nom, double poids){Chat * c = new Chat;
c->nom = nom;c->poids = poids;
return c;}
Exemple d'utilisation:
Chat * g = cree_chat("Felix", 2.5);
le rsultat de la fonction estde type pointeur sur Chat
la fonction renvoie l'adresse de
la structure alloue
-
7/25/2019 9 Memoire Support
90/115
Chat * cree_chat(string nom, double poids){Chat * c = new Chat;
c->nom = nom;c->poids = poids;
return c;}
Exemple d'utilisation:
Chat * g = cree_chat("Felix", 2.5);
-
7/25/2019 9 Memoire Support
91/115
Chat * cree_chat(string nom, double poids){Chat * c = new Chat;
c->nom = nom;c->poids = poids;
return c;}
Exemple d'utilisation:
Chat * g = cree_chat("Felix", 2.5);
"Felix" 2.5
-
7/25/2019 9 Memoire Support
92/115
Chat * cree_chat(string nom, double poids){Chat * c = new Chat;
c->nom = nom;c->poids = poids;
return c;}
Exemple d'utilisation:
Chat * g = cree_chat("Felix", 2.5);
"Felix" 2.5
-
7/25/2019 9 Memoire Support
93/115
Chat * cree_chat(string nom, double poids){Chat * c = new Chat;
c->nom = nom;c->poids = poids;
return c;}
Exemple d'utilisation:
Chat * g = cree_chat("Felix", 2.5);
"Felix" 2.5
poids
0.0
nom
c
-
7/25/2019 9 Memoire Support
94/115
Chat * cree_chat(string nom, double poids){Chat * c = new Chat;
c->nom = nom;c->poids = poids;
return c;}
Exemple d'utilisation:
Chat * g = cree_chat("Felix", 2.5);
"Felix" 2.5
poids
0.0
c
nom f e l i x
-
7/25/2019 9 Memoire Support
95/115
Chat * cree_chat(string nom, double poids){Chat * c = new Chat;
c->nom = nom;c->poids = poids;
return c;}
Exemple d'utilisation:
Chat * g = cree_chat("Felix", 2.5);
"Felix" 2.5
poids
2.5
c
nom f e l i x
-
7/25/2019 9 Memoire Support
96/115
Chat * cree_chat(string nom, double poids){Chat * c = new Chat;
c->nom = nom;c->poids = poids;
return c;}
Exemple d'utilisation:
Chat * g = cree_chat("Felix", 2.5);
"Felix" 2.5
poids
2.5
c
nom f e l i x
-
7/25/2019 9 Memoire Support
97/115
Chat * cree_chat(string nom, double poids){Chat * c = new Chat;
c->nom = nom;c->poids = poids;
return c;}
Exemple d'utilisation:
Chat * g = cree_chat("Felix", 2.5);
poids
2.5
nom f e l i x
-
7/25/2019 9 Memoire Support
98/115
Chat * cree_chat(string nom, double poids){Chat * c = new Chat;
c->nom = nom;c->poids = poids;
return c;}
Exemple d'utilisation:
Chat * g = cree_chat("Felix", 2.5);
poids
2.5
nom f e l i x
g
Pointeur sur structure en paramtre
-
7/25/2019 9 Memoire Support
99/115
Pointeur sur structure en paramtre
d'une fonction
void demande_poids(Chat * chat){cout chat->poids;
}
Exemple d'utilisation:
Chat * g = cree_chat("Felix", 0.0);demande_poids(g);
Chat g2;g2.nom = "Garfield";demande_poids(&g2);
-
7/25/2019 9 Memoire Support
100/115
void demande_poids(Chat * chat)
{cout chat->poids;
}
Exemple d'utilisation:Chat * g = cree_chat("Felix", 0.0);demande_poids(g);
Chat g2;g2.nom = "Garfield";demande_poids(&g2);
poids
0.0
nom f e l i x
g
-
7/25/2019 9 Memoire Support
101/115
void demande_poids(Chat * chat)
{cout chat->poids;
}
Exemple d'utilisation:Chat * g = cree_chat("Felix", 0.0);demande_poids(g);
Chat g2;g2.nom = "Garfield";demande_poids(&g2);
poids
0.0
nom f e l i x
g
-
7/25/2019 9 Memoire Support
102/115
void demande_poids(Chat * chat)
{cout chat->poids;
}
Exemple d'utilisation:Chat * g = cree_chat("Felix", 0.0);demande_poids(g);
Chat g2;g2.nom = "Garfield";demande_poids(&g2);
poids
0.0
nom f e l i x
g
chat
-
7/25/2019 9 Memoire Support
103/115
void demande_poids(Chat * chat)
{cout chat->poids;
}
Exemple d'utilisation:Chat * g = cree_chat("Felix", 0.0);demande_poids(g);
Chat g2;g2.nom = "Garfield";demande_poids(&g2);
poids
0.0
nom f e l i x
g
chat
-
7/25/2019 9 Memoire Support
104/115
void demande_poids(Chat * chat)
{cout chat->poids;
}
Exemple d'utilisation:Chat * g = cree_chat("Felix", 0.0);demande_poids(g);
Chat g2;g2.nom = "Garfield";demande_poids(&g2);
poids
0.0
nom f e l i x
g
chat
-
7/25/2019 9 Memoire Support
105/115
void demande_poids(Chat * chat)
{cout chat->poids;
}
Exemple d'utilisation:Chat * g = cree_chat("Felix", 0.0);demande_poids(g);
Chat g2;g2.nom = "Garfield";demande_poids(&g2);
poids
2.5
nom f e l i x
g
chat
-
7/25/2019 9 Memoire Support
106/115
void demande_poids(Chat * chat)
{cout chat->poids;
}
Exemple d'utilisation:Chat * g = cree_chat("Felix", 0.0);demande_poids(g);
Chat g2;g2.nom = "Garfield";demande_poids(&g2);
poids
2.5
nom f e l i x
g
-
7/25/2019 9 Memoire Support
107/115
void demande_poids(Chat * chat)
{cout chat->poids;
}
Exemple d'utilisation:Chat * g = cree_chat("Felix", 0.0);demande_poids(g);
Chat g2;g2.nom = "Garfield";demande_poids(&g2);
g2
poids
?
nom
-
7/25/2019 9 Memoire Support
108/115
void demande_poids(Chat * chat)
{cout chat->poids;
}
Exemple d'utilisation:Chat * g = cree_chat("Felix", 0.0);demande_poids(g);
Chat g2;g2.nom = "Garfield";demande_poids(&g2);
g2
poids
?
nom G a r f i e l d
-
7/25/2019 9 Memoire Support
109/115
void demande_poids(Chat * chat)
{cout chat->poids;
}
Exemple d'utilisation:Chat * g = cree_chat("Felix", 0.0);demande_poids(g);
Chat g2;g2.nom = "Garfield";demande_poids(&g2);
g2
poids
?
nom G a r f i e l d
-
7/25/2019 9 Memoire Support
110/115
void demande_poids(Chat * chat)
{cout chat->poids;
}
Exemple d'utilisation:Chat * g = cree_chat("Felix", 0.0);demande_poids(g);
Chat g2;g2.nom = "Garfield";demande_poids(&g2);
g2
poids
?
nom G a r f i e l d
chat
-
7/25/2019 9 Memoire Support
111/115
void demande_poids(Chat * chat)
{cout chat->poids;
}
Exemple d'utilisation:Chat * g = cree_chat("Felix", 0.0);demande_poids(g);
Chat g2;g2.nom = "Garfield";demande_poids(&g2);
g2
poids
?
nom G a r f i e l d
chat
-
7/25/2019 9 Memoire Support
112/115
void demande_poids(Chat * chat)
{cout chat->poids;
}
Exemple d'utilisation:Chat * g = cree_chat("Felix", 0.0);demande_poids(g);
Chat g2;g2.nom = "Garfield";demande_poids(&g2);
g2
poids
?
nom G a r f i e l d
chat
-
7/25/2019 9 Memoire Support
113/115
void demande_poids(Chat * chat)
{cout chat->poids;
}
Exemple d'utilisation:Chat * g = cree_chat("Felix", 0.0);demande_poids(g);
Chat g2;g2.nom = "Garfield";demande_poids(&g2);
g2
poids
3.2
nom G a r f i e l d
chat
-
7/25/2019 9 Memoire Support
114/115
void demande_poids(Chat * chat)
{cout chat->poids;
}
Exemple d'utilisation:Chat * g = cree_chat("Felix", 0.0);demande_poids(g);
Chat g2;g2.nom = "Garfield";demande_poids(&g2);
g2
poids
3.2
nom G a r f i e l d
chat
-
7/25/2019 9 Memoire Support
115/115
void demande_poids(Chat * chat)
{cout chat->poids;
}
Exemple d'utilisation:Chat * g = cree_chat("Felix", 0.0);demande_poids(g);
Chat g2;g2 nom = "Garfield";
g2
poids
3.2
nom G a r f i e l d