0

我试图理解一个动态数组。在这种情况下 - 一个指针数组。

这个程序对我来说没问题 - 它正在运行,一切都很好。

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

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

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

不,您在堆中为sizeof(POINT*)(指向的指针POINT,恰好也是 8 个字节)的 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 回答