Reputation: 105
I am trying to understang a dynamic array. In this case - an array of pointers.
This program is Ok to me - it is working, everything is fine.
What troubles me is how the array is organized in the heap.
Let us launch it, that will be our example:
pn 00456878
pn[0] 003AFB90
pn[1] 003AFB80
pn[2] 003AFB70
Will you be so kind as to help me understand three matters:
1) Why the address of pn[0] is higher than that of pn[2]? I seemed to have assigned pn[0] before pn[1] and pn[2]?
2) I allocated memory in the heap for 3 elements of sizeof(POINT). sizeof(POINT) = 8. 003AFB70 + 8 = 3AFB78. Why the next element is 003AFB80?
3) I have formed an opinion that an array in the heap looks as follows:
pn->pn[0] pn[1] pn[2]
pn is a base address. The address of pn[0] = base address + 0. Judging from what I can see here we can conclude that there is a gap between a base address and the first element. Is it for some auxiliarry data or what is it for?
Thank you in advance.
My code is:
#include "stdafx.h"
#include <iostream>
using namespace std;
struct POINT
{
int x;
int y;
};
POINT ** pn;
POINT ** tmp;
int _tmain(int argc, _TCHAR* argv[])
{
int counter = 3;
POINT p_tmp;
cout << "sizeof(POINT): " << sizeof(POINT) << endl;
pn = new POINT * [counter];
POINT a = {0, 0};
POINT b = {1, 1};
POINT c = {2, 2};
pn[0] = &a;
pn[1] = &b;
pn[2] = &c;
cout << "pn "<< pn << endl;
cout << "pn[0] "<< pn[0] << endl;
cout << "pn[1] "<< pn[1] << endl;
cout << "pn[2] "<< pn[2] << endl;
cin.get();
POINT m = * pn[0];
POINT n = * pn[1];
POINT k = * pn[2];
cout << m.x << ","<<m.y<< endl;
cout << n.x << ","<<n.y<< endl;
cout << k.x << ","<<k.y<< endl;
cin.get();
tmp = new POINT * [counter];
memcpy(tmp, pn, (counter * sizeof(POINT)));
for (int i = 0; i < counter; i++)
{
cout << "tmp[" << i << "] "<< tmp[i] << endl;
}
cin.get();
delete[] pn;
pn = tmp;
m = * pn[0];
n = * pn[1];
k = * pn[2];
cout << m.x << ","<<m.y<< endl;
cout << n.x << ","<<n.y<< endl;
cout << k.x << ","<<k.y<< endl;
cin.get();
return 0;
}
Upvotes: 0
Views: 158
Reputation: 37955
Your confusion arises from the fact that your array contains POINT*
s and not POINT
s.
Why the address of pn[0] is higher than that of pn[2]? I seemed to have assigned pn[0] before pn[1] and pn[2]?
It's not the address of pn[0]
that you are printing, it's its value. The address of pn[0]
is denoted by &pn[0]
.
POINT a = {0, 0};
POINT b = {1, 1};
POINT c = {2, 2};
pn[0] = &a;
pn[1] = &b;
pn[2] = &c;
Here you put in pn
the addresses of a
, b
and c
, which are POINTS
you declared on the stack. The stack grows from upper addresses to lower addresses, therefore &a
> &b
> &c
.
I allocated memory in the heap for 3 elements of sizeof(POINT). sizeof(POINT) = 8. 003AFB70 + 8 = 3AFB78. Why the next element is 003AFB80?
No, you allocated memory in the heap for 3 elements of sizeof(POINT*)
(pointer to POINT
, which happen to also be 8 bytes). You allocated an array of three pointers on the heap, but the pointees are on the stack.
In the end, your array looks like this:
(some address) pn-> (00456878) pn[0]-> (003AFB90) a
(00456880) pn[1]-> (003AFB80) b
(00456888) pn[2]-> (003AFB70) c
The pointer pn
is static memory, but points to 3 pointers on the heap that point back to 3 elements on the stack.
If you wanted to have everything on the heap, you'd do it like this:
Point **pn = new POINT*[counter];
for (int i = 0; i < counter; ++i)
pn[i] = new POINT;
In this layout, the pointer pn
is in static memory, but points to 3 pointers on the heap that point to 3 elements on the heap.
Upvotes: 4