2013-04-09 76 views
3
#include<stdio.h> 

int* a(int* b){ 
int a = 20; 
printf("\n \n"); 
if(a == 20){ 
    printf("\n return from if a : 0x%x \n",a); 
    return &a; 
} 
else{ 
    printf("\n returning from else b : 0x%x\n",b); 
    return b; 
} 
} 

int main(){ 
int n = 10; 
int *k,*m; 
k = &n; 
m = a(k); 
printf("\n m ; 0x%x m : %d \n",m,*m); 
return 0; 
} 

這裏我返回返回指針函數的局部變量。在函數退出期間,所有變量都將從堆棧內存中移出,但函數如何仍然保留地址'a'處的值並打印數據?本地變量地址可以保存在返回指針的函數中

O/P:

return from if a : 0xbfd8cf14 

m ; 0xbfd8cf14 m : 20 

的地址被保持在指針m和它正確打印的值。我試過改變不同的號碼。

+1

標記爲C++,但完全相關:http:// stackoverflow。com/questions/6441218/can-a-local-variables-memory-be-accessible-scope- – chris 2013-04-09 13:38:51

+0

@chris:這個鏈接有一個很好的解釋。謝謝。 – Angus 2013-04-09 13:56:54

+1

酒店房間的答案在這裏有點出名。 – chris 2013-04-09 13:58:16

回答

3

通過聲明static int a = -1;可以使返回值「可靠」,即使從函數返回後也會使a持續存在......但在很多情況下,這是一個非常糟糕的主意......尤其是如果您將要多線程。

這就是說...返回一個指向臨時(本地)變量的指針會在運行時造成嚴重破壞。所以,你永遠不想這麼做......你需要將它變成一個靜態的本地或找到一個更好的方式來處理它。

擴展回答您的編輯後:當你將-1a作爲一個局部變量,你實際上是在堆棧和&a點,該位置上的某個位置存儲-1。從函數返回時,堆棧不會被銷燬,但行爲現在是未定義的,因爲當地址是有效指針時,該地址的內容可能已被修改......例如,如果調用另一個函數將數據推入堆棧並/或聲明局部變量,它們可能已經覆蓋了您所期望的值。另外,誰知道優化器可能注入了什麼瘋狂。所以......它可能工作如果你碰巧在讀取其他東西之前先讀取它的值......但是你無法保證它能正常工作,並且它通常會因實現而異。

6

這是你的程序調用未定義的行爲。它可以自由地打印任何東西(或崩潰,或做任何想要的)。 (也許這是實際發生的事情:「從記憶中移除」並不意味着持有該變量的記憶被毀滅,置於火中或被魔法師消失,僅僅是因爲它失效了,因爲它是一個函數內的自動變量,很可能發生的事情只是當函數返回時棧指針被移位,使得該變量無效但完好無損。不要依賴於此)

2

這是一個undefined行爲。當你離開函數時,堆棧沒有被清理,所以變量的實際值仍然存在,但你不應該訪問它。在顯示變量的內容之前,嘗試調用另一個函數。嘗試使用-O3編譯可能的不同行爲。

3

退出函數後返回的指針將無效。這是一個未定義的行爲。

保存的指針指向內存中的一個位置,您無權再讀取/寫入它。

要保持地址有效,請使用static變量。

static int a = -1; 
// ... 
return &a;