La variabile creata sul heap, 2 puntatori che puntano alla stessa variabile hanno indirizzi diversi?
-
28-09-2019 - |
Domanda
Ho appena imparato la differenza tra lo stack e il mucchio. Dopo aver creato una funzione che allocherà dinamicamente la memoria sul heap per me, restituisco il puntatore e visualizzo (dentro e fuori dalla funzione) l'indirizzo e il valore di ciascun puntatore.
I valori sono gli stessi, che mi aspettavo, ma gli indirizzi allo stesso pezzo di memoria sul mucchio sono diversi, cosa che non mi aspettavo.
Come mai? PHEAP2 e PTEMP non dovrebbero indicare lo stesso indirizzo?
#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;
}
Produzione:
*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 . . .
Soluzione
Stai segnalando l'indirizzo dei puntatori, non l'indirizzo a cui punta il puntatore. Naturalmente l'indirizzo del puntatore sarà diverso per pTemp
e pHeap2
; Questi sono diversi suggerimenti che indicano lo stesso indirizzo in memoria. Rimuovi il &
prefisso pTemp
e pHeap2
per vedere i risultati che ti aspetti.
L'immagine è qualcosa di simile:
0042FBB0 0042FBC0 0042FCB4
------------ ------ ------------
| 0042FBC0 |------>| 20 |<------| 0042FBC0 |
------------ ------ ------------
pTemp pHeap2
Qui hai quello &pTemp
è 0042FBB0
e &pHeap2
è 0042FCB4
. Ho inventato un indirizzo per l'indirizzo che pTemp
e pHeap2
stanno indicando (ovviamente, i risultati potrebbero variare da una corsa all'altro) e se rimuovi il &
prefisso pTemp
e pHeap2
allora vedresti 0042FBC0
stampato invece in ogni caso.
Altri suggerimenti
Sì, pTemp
e pHeap2
dovrebbe essere lo stesso. Ma &pTemp
e &pHeap2
sono diversi. Questo perché il &
L'operatore restituisce un puntatore al suo operando. Così pTemp
è un puntatore a un int
, mentre &pTemp
è un puntatore a un puntatore a un int
.
&pHeap2
Non restituisce il valore del puntatore, restituisce l'indirizzo del puntatore. Questo è a causa del &
, che in questo contesto significa "l'indirizzo di".
cioè a 0042fcb4 in memoria, c'è un puntatore che punta a 0042FBB0 (cioè in un ambiente di grande endiano, vedresti 00 42 fb b0 a 0042fcb4).