2016-02-13 29 views
1

我有以下程序:存儲位置進行訪問,甚至在函數調用結束

// This is with ** int r = 99; ** line commented 
[email protected] (~/psets/pset5/pset5_test): ./PointerAddresss 
Value of x is 2 and its address is 0xbfdba7c4 
Value of y is 33 and its address is 0xbfdba794 
[email protected] (~/psets/pset5/pset5_test): size PointerAddresss 
    text data  bss  dec  hex filename 
    1250  280  4 1534  5fe PointerAddresss 


// This is with ** int r = 99; ** line un-commented 
[email protected] (~/psets/pset5/pset5_test): ./PointerAddresss 
Value of x is 2 and its address is 0xbf8a98e4 
Value of y is 33 and its address is 0xbf8a98b4 
[email protected] (~/psets/pset5/pset5_test): size PointerAddresss 
    text data  bss  dec  hex filename 
    1266  280  4 1550  60e PointerAddresss 
[email protected] (~/psets/pset5/pset5_test): 

#include <stdio.h> 
#include <stdlib.h> 

int* testPointerReturnType(); 

int main(void) 
{ 
    int x = 2; 
    printf("Value of x is %d and its address is %p\n", x, &x); 
    int* y = testPointerReturnType(); 
    printf("Value of y is %d and its address is %p\n", *y, y);  
} 

int* testPointerReturnType() 
{ 
    int x = 33; 
    int r = 99; 
    return &x; 
} 

下面是我的總體O/P(我將在我的問題下面來討論這個問題)

下面是我的問題:

  1. 我返回一個局部變量的內存地址,但我仍能夠訪問LOCAT之後,該功能完成執行後。怎麼樣?內存位置是否有可能保留該值並且尚未被覆蓋。這意味着如果我的程序只調用了一個函數,並且該函數正在返回一個內存地址,那麼我仍然可以訪問局部變量的內存地址並獲得相同的確切值,因爲沒有調用其他函數?
  2. 如果我保留int r = 99;作爲評論,然後我得到1250在文本和dec。如果我取消註釋,那麼我得到1266,這基本上意味着增加16個內存位置,但爲什麼增加16個內存位置時爲4個字節的int?此外,我知道文本/代碼段然後什麼是dec
+6

你爲什麼會認爲CPU週期會浪費在擦除從堆棧中彈出的清除內存?數據仍然存在,直到被覆蓋,但它是未定義的行爲,試圖訪問它。 –

+0

@JohnColeman這就是我也想過的,但我不確定,筆記/教程不清楚指出。我的第二個問題呢? – hagrawal

+1

我認爲@ DavidHoelzer的回答指出了你的第二個問題 –

回答

7

存儲器位置仍然保留該值,除非堆棧的大小再次增加到足以覆蓋該值,但您的操作基於未定義的行爲。它可能意味着沒有其他函數被調用,但它也可能意味着沒有其他函數需要分配堆棧上的這麼多的空間才能運行。

您看到分配的內存比預期多的原因是堆棧對齊。如果您閱讀了適用於您的平臺的應用程序二進制界面文檔,您會發現這很好描述。

我不願意提到這一點,但如果您在函數中將局部變量標記爲static,您仍然在做非常糟糕的事情,但您可以在函數調用通過指針結束後可靠地繼續訪問該值,因爲值將不再分配在堆棧上。

最後,我剛看到你最後一個問題。 dec表示小數。如果轉換0x60e爲十進制你會得到1550


大衛的約棧對齊的更多信息,投入他的回答從他的評論 - hagrawal。

訪問元素的速度和調用中的一致性需要棧對齊。這種方式最好在內存中對齊,以便快速訪問,並且被調用的函數不需要「想知道」事情會在哪裏。這意味着分配一個字節通常會導致 在堆棧中分配的2,4,8,16甚至更多字節,所有 取決於對齊要求。

+0

謝謝您的輸入。對於第一個問題,這也是我的想法,但我不確定,筆記/教程不清楚指出。對於第二個問題 - 堆棧對齊?我確實聽說過數據結構對齊,但不是堆棧對齊。我會在網上閱讀更多關於這方面的內容,但是如果能夠對此進行點亮並提出相關的重要觀點,那麼這對我和其他未來的讀者都會有好處。我知道「靜態」的東西,並且對未定義的行爲進行操作。一個問題仍然沒有答案 - 「*什麼是」dec「*」。如果你也可以投射光線,那將是非常棒的。 – hagrawal

+1

訪問元素的速度和調用的一致性需要棧對齊。通過這種方式,內存中的事情最好與快速訪問保持一致,被調用的函數不必「疑惑」事物會在哪裏。這意味着分配一個字節通常會導致在堆棧上分配2,4,8,16甚至更多字節,全部取決於對齊要求。 –

+0

哦,我回答了dec的事......最後一段 –

相關問題