2014-03-01 94 views
1

遞歸調用放在系統堆棧上,這是我讀過的。但如果這是真的,爲什麼在下面的程序中,我得到了所有rec()所調用的相同地址。他們不應該在堆棧上有連續的地址嗎?爲什麼這些調用具有相同的內存地址?

void rec(int n) 
    { 

      printf("%d -> %p\n",n,rec); 
      if(n ==0) 
       return; 
      else 
       rec(n-1); 

    } 

當我打電話REC(5)在我的main()的代碼,它給瞭如下輸出,

5 -> 0x4004f4 
4 -> 0x4004f4 
3 -> 0x4004f4 
2 -> 0x4004f4 
1 -> 0x4004f4 
0 -> 0x4004f4 

,對不起,那如果我的查詢是太基本。但是我不能提出任何解釋,除非是由於某種編譯器優化。但我不確定它。同時,請告訴我任何可以幫助我在運行時查看程序內存(不是大小,但內容)的工具。

在此先感謝!

UPDATE:

我在每次調用增加了一個局部變量i,我得到了我想要看到的。

5 -> 0x4004f4 0x7fff507d376c 
    4 -> 0x4004f4 0x7fff507d373c 
    3 -> 0x4004f4 0x7fff507d370c 
    2 -> 0x4004f4 0x7fff507d36dc 
    1 -> 0x4004f4 0x7fff507d36ac 
    0 -> 0x4004f4 0x7fff507d367c 

謝謝@EVERYONE :)

+2

您打印的是rec的地址,與堆棧無關。 –

+1

如果您想要堆棧地址,請嘗試輸出局部變量的地址。 –

+0

謝謝@CharlieBurns – kuroop

回答

3

爲什麼它打印相同的地址?

功能

void rec(int n) 

是在存儲器的代碼段(其是隻讀的),並要打印其中函數被定位在相同的地址。

要查看內存

您可以使用objDumphere是你如何使用它。

+0

好的..我知道了@brokenfoot。對我很有啓發。你對我的第二個問題有什麼建議嗎? – kuroop

+0

嘗試[ObjDump](http://linux.about.com/library/cmd/blcmdl1_objdump.htm),其[使用方法](http://www.thegeekstuff.com/2012/09/objdump-examples/) – brokenfoot

1

不,該函數的地址在內存中的某處是靜態的。在遞歸調用期間你在堆棧上推送的是一個返回地址和所有局部變量,如果該函數在範圍內。 Here是一個很好的教程。

1

在你的功能,當你說:

printf("%d -> %p\n",n,rec); 

你問的代碼的地址功能rec(int)。編譯器只創建函數的一個副本,所以你看到了這個。有沒有辦法(據我所知)來訪問在堆棧上您是來自標準C.

1

rec是功能,並且只有一個REC在你的代碼,所以沒有理由地址改變

1

功能 - 呼叫確實放在堆棧上,但它們不是功能本身,而是所謂的堆棧幀。它們包含參數,局部變量和返回地址(可能還有更多)。

但是,當您打印rec的地址時,不會獲得當前堆棧幀的地址,而是該函數的代碼地址。這總是相同的,因爲代碼本身不會改變。

可以有效看到這個當您打印本地變量,而不是地址:

printf("%p -> %p\n", &n, rec); 

輸出示例:

0028fee0 -> 004016d9 
0028fec0 -> 004016d9 
0028fea0 -> 004016d9 
0028fe80 -> 004016d9 
0028fe60 -> 004016d9 
0028fe40 -> 004016d9 

注意,而第二指針保持不變(它是函數指針),每次調用都會有所不同,因爲每次調用時都會有不同的變量。

相關問題