2012-10-24 28 views
1

誰知道爲什麼輸出是這樣的?
儘管使用這樣的指針是錯誤的,但我仍然想明白爲什麼它的行爲如此。如何解釋這個奇怪的輸出?關於指針和臨時變量

int* foo() 
{ 
    int a=9; 
    int *p=&a; 
    //definitely not right to return a pointer to an invalid varible 
    return p; 
} 
int main(int argc, char* argv[]) 
{ 
    int *p=foo(); 
    cout<<*p<<endl;//9 
    cout<<*p<<endl;//2357228 
    *p=2; 
    cout<<*p<<endl;//2 
    (*p)++; 
    cout<<*p<<endl;//2357229 
    cout<<*p<<endl;//2357228 
    cout<<*p<<endl;//2357228 
    (*p)++; 
    cout<<*p<<endl;//2357229 
    cout<<*p<<endl;//2357228 

    return 0; 

} 
+6

這就是未定義行爲的美妙之處。 – Mysticial

+2

http://stackoverflow.com/questions/6441218/can-a-local-variables-memory-be-accessed-outside-its-scope – chris

+1

你對C++語言感興趣嗎?或者你對這種情況下編譯器產生的特定代碼感興趣嗎?如果前者,語言規範在這個問題上沒有什麼可說的,就不要這樣做。如果是後者,請看組件輸出。 –

回答

1

雖然使用這樣的指針是錯誤的,但我仍然希望 理解爲什麼它的行爲如此。

因爲p指向堆棧內存中一個不斷被cout的< <方法寫入的位置。每次使用cout時,p的值可能會改變。

這樣的代碼很危險,因爲它會破壞堆棧並導致程序崩潰。

0

你需要記住的是,a和p都是作用域級別的變量。因此,返回只存在於堆棧中的變量的地址(但不是在堆上動態分配的)是未定義的行爲。由於我們不知道一旦剩下那個地址空間就寫到那裏。 Ergo,返回一個指向局部變量的指針是未定義的行爲。

2

返回指向函數本地變量的指針/引用導致未定義的行爲。一個本地/自動變量保證僅在範圍內({,})有效並且有效,在該範圍內其定義不超出該範圍。

未定義的行爲意味着程序可以顯示任何行爲,並且可以通過C/C++標準來執行此操作。嘗試查找發生未定義行爲後觀察到的行爲的推理是沒有意義的,因爲此行爲可能/可能不一致或不可信賴。

在光明的一面,任何優秀的商業編譯器都會爲您提供有關此類代碼的警告。

+0

是的,編譯器可以在未定義時做任何事情。但是必須有一種方式產生不確定性。存在一些機制,對嗎?就像馬特解釋的那樣。 – duleshi

+0

我的意思是,當面對未定義的時候,通常可以列出全部或部分的可能性:它通過這種方式產生這個結果,並且通過這種方式產生結果等。 – duleshi

+0

@duleshi:歸結爲問題:***你能定義一些本身未定義的東西嗎?*** –