Variable créée sur le tas, 2 pointeurs pointant vers une même variable ont des adresses différentes?
-
28-09-2019 - |
Question
Je viens d'apprendre la différence entre la pile et le tas. Après la création d'une fonction qui va allouer dynamiquement la mémoire sur le tas pour moi, je retourne le pointeur et l'affichage (dans et hors de la fonction) l'adresse et la valeur de chaque pointeur.
Les valeurs sont les mêmes, que je m'y attendais, mais les adresses à la même partie de la mémoire sur le tas sont différents, que je ne me attendais pas.
Pourquoi? Ne devrait pas le point pHeap2 et Ptemp à la même adresse?
#include <iostream>
using namespace std;
int* intOnHeap(); // returns an int on the heap
int main()
{
int* pHeap = new int; // new operator allocates memory on the heap and returns its address
// 'new int' allocates enough memory on heap for one int and returns the address on the heap for that chunk of memory
// 'int* pHeap' is a local pointer which points to the newly allocated chunk of memory
*pHeap = 10;
cout << "*pHeap: " << *pHeap << "\n\n";
int* pHeap2 = intOnHeap();
cout << "pHeap2:\n-----------" << endl;
cout << "Address:\t" << &pHeap2 << "\n";
cout << "Value:\t\t" << *pHeap2 << "\n\n";
cout << "Freeing memory pointed to by pHeap.\n\n";
delete pHeap;
cout << "Freeing memory pointed to by pHeap2.\n\n";
delete pHeap2;
// get rid of dangling pointers
pHeap = 0;
pHeap2 = 0;
system("pause");
return 0;
}
int* intOnHeap()
{
int* pTemp = new int(20);
cout << "pTemp:\n-----------" << endl;
cout << "Address:\t" << &pTemp << "\n";
cout << "Value:\t\t" << *pTemp << "\n\n";
return pTemp;
}
Sortie:
*pHeap: 10
pTemp:
-----------
Address: 0042FBB0
Value: 20
pHeap2:
-----------
Address: 0042FCB4
Value: 20
Freeing memory pointed to by pHeap.
Freeing memory pointed to by pHeap2.
Press any key to continue . . .
La solution
Vous rapporte l'adresse des pointeurs, pas l'adresse que le pointeur pointe. Bien sûr, l'adresse du pointeur sera différent pour pTemp
et pHeap2
; ceux-ci sont différents pointeurs qui arrivent à pointer vers la même adresse en mémoire. Retirez le &
préfixer pTemp
et pHeap2
pour voir les résultats que vous attendez.
L'image est quelque chose comme ceci:
0042FBB0 0042FBC0 0042FCB4
------------ ------ ------------
| 0042FBC0 |------>| 20 |<------| 0042FBC0 |
------------ ------ ------------
pTemp pHeap2
Ici, vous avez cette &pTemp
est 0042FBB0
et &pHeap2
est 0042FCB4
. J'ai fait une adresse à l'adresse que pTemp
et pHeap2
pointent vers (bien sûr, les résultats peuvent varier d'une exécution à toute façon) et si vous supprimez le &
préfixer pTemp
et pHeap2
vous verriez alors 0042FBC0
imprimé au lieu dans chaque cas.
Autres conseils
Oui, pTemp
et pHeap2
doit être le même. Mais &pTemp
et &pHeap2
sont différents. En effet, l'opérateur &
renvoie un pointeur sur opérande de lui. Alors pTemp
est un pointeur vers un int
, tandis que &pTemp
est un pointeur vers un pointeur sur un int
.
&pHeap2
ne retourne pas la valeur du pointeur, il renvoie l'adresse du pointeur. En effet, du &
, qui signifie ce contexte « l'adresse ».
i.e.. à 0042FCB4 en mémoire, il y a un pointeur pointant vers 0042FBB0 (par exemple dans un environnement grand-boutiste, vous verriez 00 42 FB à 0042FCB4 B0).