0

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;
}
4

1 に答える 1

4

混乱は、配列にPOINT*s ではなくPOINTs が含まれているという事実から生じます。

pn[0] のアドレスが pn[2] のアドレスよりも高いのはなぜですか? pn[1] と pn[2] の前に pn[0] を割り当てたようですか?

印刷するのはアドレスではなく、pn[0]そのです。のアドレスpn[0]で示され&pn[0]ます。

POINT a = {0, 0};
POINT b = {1, 1};
POINT c = {2, 2};

pn[0] = &a;
pn[1] = &b;
pn[2] = &c;

ここに、 、およびpnのアドレスを入れます。これらはスタック上で宣言されています。スタックは上位アドレスから下位アドレスに向かって成長するため、> > .abcPOINTS&a&b&c

sizeof(POINT) の 3 つの要素のヒープにメモリを割り当てました。sizeof(POINT) = 8. 003AFB70 + 8 = 3AFB78. なぜ次の要素は 003AFB80 なのですか?

いいえ、( 8 バイトにもなる へのsizeof(POINT*)ポインター)の 3 つの要素のヒープにメモリを割り当てました。ヒープ上POINTに 3 つのポインターの配列を割り当てましたが、ポインターはスタック上にあります

最終的に、配列は次のようになります。

(some address) pn-> (00456878) pn[0]-> (003AFB90) a
                    (00456880) pn[1]-> (003AFB80) b
                    (00456888) pn[2]-> (003AFB70) c

ポインター pnは静的メモリですが、スタック上の3 つの要素を指すヒープ上の3 つのポインターを指します。


すべてをヒープに置きたい場合は、次のようにします。

Point **pn = new POINT*[counter];

for (int i = 0; i < counter; ++i)
    pn[i] = new POINT;

このレイアウトでは、ポインター pnは静的メモリにありますが、ヒープ上の3 つの要素を指すヒープ上の3 つのポインターを指しています

于 2013-01-13T10:16:01.897 に答える