Examen 1 - pointeurs et allocation dynamique Flashcards
Données (Data segment
pour les variables globales et statiques
Code (code segment)
pour le code compilé
Tas (Heap)
pour l’allocation dynamique
Pile (Stack)
pour les variables locales
void UneFonction (int nombre3);
int nombre1;
void main()
{
Ennemi * e1;
e1 = new Ennemi;
UneFonction(7);
}
void UneFonction(int nombre3)
{
int nombre2;
}
cptInstance
nombre1
nombre2
nombre3
e1 (pointeur)
Pile
Tas
Code
Données
Main()
e1
(contenu)
class Ennemi
{
static int cptInstance;
// . . .
};
cptinstance et nombre 1 données
rien code
e1 (contenu) tas
nombre2 nombre3 e1(pointeur) pile
(la taille d’un int)
4 octets
transtyper l’adresse de a (un int*) en…. pour pouvoir visualiser le contenu de la mémoire un octet à la fois
pointeur de caractères
(unsigned char*)
Passage par valeur
Supposons que l’on possède la déclaration de fonction suivante :
int doIt(int value){
{
return value+1;
}
Supposons que l’on fasse l’appel
int b = doIt(a);
En supposant que la variable value soit à l’emplacement mémoire 0x009efda8 on obtiendra lors
de l’appel de doIt le schéma mémoire suivant :
a
52 0 0 0
0x00effc08 0x00effc09 0x00effc0A 0x00effc0B
value
52 0 0 0
0x009efda8 0x009efda9 0x009efdaA 0x009efdaB
Nous obtiendrons deux emplacements mémoire distincts qui contiendront cependant les mêmes
valeurs
Passage par référence
Lorsque l’on passe un paramètre par référence, on utilise l’adresse de l’original. Une fa çon
d’obtenir l’adresse de l’original est d’utiliser l’opérateur &.
int a = 52;
int* ptrA = &a;
Si l’on veut accéder ce qui se trouve à une adresse on utilise l’opérateur *.
int valeurDeA = *ptrA;
// Évidemment ici valeurDeA et a auront la même valeur soit 52
ne fa çon
d’obtenir l’adresse de l’original
l’opérateur &
Si l’on veut accéder ce qui se trouve à une adresse
l’opérateur *
Si l’on exécute les instructions suivantes :
int a = 52;
int* ptrA = &52;
int* pValeur = ptrA + 1;
la valeur de pValeur sera celle de ptrA augmentée de 4 octets car ptrA est un pointeur de int
et un int occupe 4 octets en mémoire.
int* pData;
// Ne pointe vers RIEN DE CONCRET. On ne veut pas faire cela.
intialiser un pointeur
int* pData = new int;
est alors possible d’accéder au contenu de pData pour y placer des infos ou pour lire le contenu
std::cout «_space;*pData;
ou
*pData = 80;
Si vous tentez de lire le contenu d ’un emplacement mémoire AVANT d’y affecter une valeur,…
le
contenu est indéterminé
responsables de libérer la mémoire allouée avec new
lorsqu’elle n’est plus nécessaire.
delete pData; Le pointeur peut alors être réutilisé pour un autre emplacement mémoire mais le contenu
désormais pointé est indéterminé.
void doIt()
{
int * pData = new int;
pData = 80;
}
void main()
{
doIt();
}
A la fin de l’exécution de la fonction doIt, la portée de la variable local pData sera terminée. La
variable sera libérée MAIS PAS L’ESPACE MÉMOIRE POINTÉ par pData. Cela causera une fuite de
mémoire
chaque utilisation de new doit s’accompagner
d’un delete
correspondant.
une fonction ou une méthode qui alloue la mémoire
est
généralement responsable de la libérer. En programmation objet, l’objet qui allouera de la
mémoire sera responsable de la libérer lorsque sa portée prendra fin.
Allocation d’un tableau
int* pData = new int[10];
Pour accéder à un élément d’un tableau
std::cout «_space;pData[4];
est l’équivalent de
std ::cout «_space;*(pData+4);