地址

2010-08-19 61 views
5

校正:地址

我弄亂了與指針地址和地址指針指向的概念,所以下面的代碼已被修改。現在它打印出我想要的,變量a,c,i,j,k,p在堆棧上,而變量b,d在堆上。靜態和全局變量位於另一個段上。非常感謝你們所有人!


嗯,我知道這兩個概念進行了深入的討論......不過我還是有以下代碼的問題:

#include <iostream> 
using namespace std; 

class A { 

}; 

int N = 10; 

void f(int p) { 
    int j = 1; 
    float k = 2.0; 
    A c; 
    A* d = new A(); 
    static int l = 23; 
    static int m = 24; 
    cout << "&c: " << &c << endl; 
    cout << "&d: " << d << endl; 
    cout << "&j: " << &j << endl; 
    cout << "&k: " << &k << endl; 
    cout << "&l: " << &l << endl; 
    cout << "&m: " << &m << endl; 
    cout << "&p: " << &p << endl; 
} 

int main() { 
    int i = 0; 
    A* a; 
    A* b = new A(); 
    cout << "&a: " << &a << endl; 
    cout << "&b: " << b << endl; 
    cout << "&i: " << &i << endl; 
    cout << "&N: " << &N << endl; 
    f(10); 
    return 0; 
} 

我的結果是:

&a: 0x28ff20 
&b: 0x7c2990 
&i: 0x28ff1c 
&N: 0x443000 
&c: 0x28fef3 
&d: 0x7c0f00 
&j: 0x28feec 
&k: 0x28fee8 
&l: 0x443004 
&m: 0x443008 
&p: 0x28ff00 

這非常有趣,除了全局變量N和函數f中的兩個靜態變量l和m,所有其他變量的地址似乎都在一起。 (注意:代碼和結果已被修改,與此處所述內容不一致)。

我已經搜索了很多關於堆棧和堆的內容。常識是,如果一個對象是由「新」創建的,那麼它就在堆上。局部變量(例如上面示例中的j和k)在堆棧中。但在我的例子中似乎並非如此。它依賴於不同的編譯器,還是我的理解錯誤?

非常感謝大家。

+0

我不明白你的問題,你爲什麼認爲一個變量是基於你顯示的地址在堆棧或堆上。 – 2010-08-19 20:40:51

+0

這真的沒有意義。你不能對你的內存在哪裏進行任何推斷 – Falmarri 2010-08-19 20:41:40

+0

[C++中正確的堆棧和堆使用情況?](http://stackoverflow.com/questions/599308/proper-stack-and-heap-usage -in-c) – 2010-08-19 20:42:51

回答

14

你的理解是錯誤的。例如,b是一個指針 - 如果要創建由new創建的對象的地址,則需要打印出b而不是&bb是一個局部變量,因此它本身(位於&b)位於堆棧中。

對於您的示例,N,lm大概可能位於可執行文件的數據部分中。正如你所看到的,他們有類似的地址。您打印出的其他所有變量都在堆棧中 - 它們的地址同樣相似。其中一些是指向從堆中分配的對象的指針,但是沒有任何打印輸出會顯示該對象。

1

如果你想什麼d點的地址打印到(在這種情況下,它指向在堆上的對象),做

cout << "d: " << d << endl; 

,將打印指針的值,和值指針的地址是它指向的對象的地址。

你的代碼有

cout << "&d: " << &d << endl; 

這將打印的d地址,因爲你裏面主要定義d,這將是在棧上,你打印你的指針的地址。指針本身和它指向的對象,它們是2個獨立的東西,具有不同的地址。

2

你的理解是正確的。

  • 局部變量分配在堆棧上。
  • 動態分配的對象分配在堆上。

儘管在您的示例中您始終採用本地變量的地址。
例如:打印出d而不是d的地址。由於d是一個局部變量(所以地址類似於c),但它是一個指針變量,指向動態分配的對象(that is on the heap)

編譯器如何實現堆棧和堆雖然會有所不同。

在現代操作系統中,堆棧和堆甚至可以共享相同的區域(即,您可以通過在堆中分配塊來實現堆棧)。

+0

這是真的,但不是爲什麼OP獲得他的價值。 :-) – Omnifarious 2010-08-19 20:44:00

0

從純粹的C++角度來看,兩種形式之間的區別僅在於如何管理對象的生命週期。

From here, good read

0

靜態變量在數據段中。你也可以混合一個指針的地址和它的值。例如a:

a是堆棧上A *類型的局部變量。 & a也給出了一個實際上在(棧上)resieds的地址。 a的值是類型A的堆對象的地址;

0

你不能依賴於各種編譯器以相同的方式做事。對於幾乎每一位的代碼,你會寫的區別堆和棧之間是沒有意義的。不要擔心。

2

在你的例子中唯一不是'一起'的是l,mN。他們是兩個靜態和一個全局,因此他們沒有被確切地分配到棧上。他們不是從堆都不是,最有可能的,他們是從模塊的。數據段。堆中唯一的地址應該是地址b指向的地址,但是您打印的地址是b本身,而不是它指向的地址。

+1

另外請注意,你的'neirness'是相當具體的平臺。在像IA64這樣的平臺上,這些地址可能看起來完全不同(例如'&p'''''''''''''''''''''''''''''''''''''''''''''''''),它是'後備存儲'棧,參見http://blogs.msdn.com/b/slavao/存檔/ 2005/03/19/399117.aspx – 2010-08-19 20:50:39

0

一個可能無法安全地假設關於事物相對於那些在堆上也不,對於這個問題中堆疊的相對地址什麼,未全部來自同一陣列所得出的或分配的任何指針的相對地址(通過malloc,calloc等)塊。我甚至不確定需要進行排名的指針。