Variable created on the heap, 2 pointers pointing to same variable have different addresses?
-
28-09-2019 - |
Pergunta
I just learned the difference between the stack and the heap. After creating a function which will dynamically allocate memory on the heap for me, I return the pointer and display (in and out of the function) the address and value of each pointer.
The values are the same, which I expected, but the addresses to the same chunk of memory on the heap are different, which I did NOT expect.
Why? Shouldn't pHeap2 and pTemp point to the same address?
#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;
}
Output:
*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 . . .
Solução
You are reporting the address of the pointers, not the address that the pointer is pointing to. Of course the address of the pointer will be different for pTemp
and pHeap2
; these are different pointers that happen to be pointing to the same address in memory. Remove the &
prefixing pTemp
and pHeap2
to see the results that you are expecting.
The picture is something like this:
0042FBB0 0042FBC0 0042FCB4
------------ ------ ------------
| 0042FBC0 |------>| 20 |<------| 0042FBC0 |
------------ ------ ------------
pTemp pHeap2
Here you have that &pTemp
is 0042FBB0
and &pHeap2
is 0042FCB4
. I made up an address for the address that pTemp
and pHeap2
are pointing to (of course, the results could vary from run to run anyway) and if you remove the &
prefixing pTemp
and pHeap2
then you would see 0042FBC0
printed instead in each case.
Outras dicas
Yes, pTemp
and pHeap2
should be the same. But &pTemp
and &pHeap2
are different. This is because the &
operator returns a pointer to it's operand. So pTemp
is a pointer to an int
, while &pTemp
is a pointer to a pointer to an int
.
&pHeap2
doesn't return the value of the pointer, it returns the address of the pointer. That's because of the &
, which in this context means "the address of".
i.e. at 0042FCB4 in memory, there's a pointer pointing to 0042FBB0 (i.e. in a big-endian environment, you'd see 00 42 FB B0 at 0042FCB4).