我正在尝试强调一个动态数组。在这种情况下-指针数组。

这个程序对我来说还可以-它正在工作,一切都很好。

困扰我的是数组在堆中的组织方式。

让我们启动它,这将是我们的示例:

pn 00456878
pn[0] 003AFB90
pn[1] 003AFB80
pn[2] 003AFB70


您是否愿意帮助我理解三件事:

1)为什么pn [0]的地址比pn [2]的高?我似乎在pn [1]和pn [2]之前分配了pn [0]?

2)我在堆中为sizeof(POINT)的3个元素分配了内存。
sizeof(POINT)= 8。
003AFB70 + 8 = 3AFB78。为什么下一个元素是003AFB80?

3)我已经形成了一种观点,认为堆中的数组如下所示:


pn->pn[0]
    pn[1]
    pn[2]



pn是基地址。 pn [0]的地址=基地址+ 0。
从我在这里看到的内容来看,我们可以得出结论,基地址和第一个元素之间存在间隙。是用于一些辅助数据还是用于什么?

先感谢您。

我的代码是:

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

最佳答案

您的困惑来自于数组包含POINT*而不是POINT的事实。


  为什么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;


在这里,您将pnab的地址放入c中,这些地址是您在堆栈中声明的POINTS。堆栈从高位地址增长到低位地址,因此&a> &b> &c


  我在堆中为sizeof(POINT)的3个元素分配了内存。 sizeof(POINT)=8。003AFB70 + 8 = 3AFB78。为什么下一个元素是003AFB80?


不,您在堆中为sizeof(POINT*)的3个元素(指向POINT的指针,恰好也是8个字节)分配了内存。您在堆上分配了三个指针的数组,但是指针位于堆栈上。

最后,您的数组如下所示:

(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个元素。

关于c++ - C++:了解动态数组,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/14302480/

10-13 07:09