2013-01-13 61 views
0

我想試着動態數組。在這種情況下 - 一個指針數組。C++:理解動態數組

這個程序對我來說很好 - 它工作,一切都很好。

麻煩的是數組是如何組織在堆中的。

讓我們啓動它,那將是我們的例子:

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個元素分配了內存。 (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; 
} 
+5

您不打印'pn [0]'的地址。您正在打印其價值。要獲取地址,請使用'&pn [0]'。 –

+0

混淆源於你使用指針數組,打印實際的指針而不是指針的地址。 –

+0

對於獎勵積分,@Pepperwork,'pn'的類型是什麼?那麼'pn [0]'呢?看起來這是你感到困惑的地方。 –

回答

4

你的困惑源於你的數組包含POINT*秒且不POINT S中的事實。

爲什麼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; 

在這裏,你擺在abcpn地址,被POINTS堆棧上聲明其。堆棧從高地址增長到低地址,因此&a>&b>&c

我在堆中爲sizeof(POINT)的3個元素分配了內存。 (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個指針堆棧


如果你想對堆的一切,你會做這樣的:

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

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

在這種佈局中,指針pn是靜態存儲器,但到3指針那指向堆上的3個元素

+0

堆組織類似? – Pepperwork

+0

@Pepperwork類似於堆棧?不,這是一個非常不同的野獸。看一看[Doug Lea的malloc](http://gee.cs.oswego.edu/dl/html/malloc.html)。 –

+0

在那裏,我添加了一些細節。我希望有所幫助。 –