2011-08-18 86 views
0

可能重複:
Can a local variable's memory be accessed outside its scope?函數返回後本地內存地址是否有效?

我是令人耳目一新有關如何存儲在內部工作原理的知識,我所面臨的困惑。下面是示例代碼

int * func(){ 
    int retval = 3; 
    return &retval; 
} 

int main(void){ 
    int *ptr = func(); 
    printf("address return from function %p and value %d\n", ptr, *ptr); 
} 

我的理解對於如何堆棧存儲器上的日常工作,是當一個函數被調用,它被壓入堆棧。一旦函數返回,此例程中局部變量的生存期將不再有效。所以返回局部變量的地址似乎是無效的,但是當我測試這個代碼時,它實際上返回它的地址,並且在函數返回後仍然有效。

我誤解了這個概念嗎?讚賞任何意見,謝謝。

+0

總之,你在做什麼是無效的,但這並不意味着它不會在某些情況下工作。 –

+0

// @Peter提到的dupe包含我見過的最好的答案之一,有近2000個upvotes .. – amit

+1

無效和不工作是兩個不同的事情。直到數據被覆蓋(通過另一個函數調用),即使您不應該也可以訪問它。如果你在'func'和'printf'之間調用了另一個函數,你會得到一些其他的數字,而不是3. – ughoavgfhw

回答

3

「測試代碼」不是確定某件事是否有效的有意義的方法。你的代碼產生未定義的行爲。未定義行爲的一種可能表現是代碼可能似乎是「正在工作」。換句話說,你只是很幸運。

要回答這個問題:no,返回一個指向局部變量的指針是無效的,並且它不能有效的取消引用這樣一個指針。任何嘗試這樣做都會導致未定義的行爲。

+0

只是返回它並不是無效的,至少在將它轉換爲整數類型時不是無效的。這可能是一個有用的(弱,但仍然潛在有用)的熵源 - 本質上,從系統的ASLR收集熵。 –

+0

請注意,有些人**錯誤地將指針取消引用,因爲它不再有效作爲熵源。這不是合法的C,一個實現是完全合理的,使這種使用崩潰。但我的例子是合法的。 –