2013-08-17 79 views
2

任何機構有任何想法爲何此代碼打印a而不是b爲什麼指針正好改變?

我測試mainArea.root->rightBro當我cout東西的變化值。但爲什麼?

#include<iostream> 

using namespace std; 

struct triangle{ 
    triangle *rightBro; 
}; 

struct area{ 
    triangle *root; 
} mainArea; 

void initialize(){ 
    triangle root; 
    mainArea.root = &root; 
} 

int main() 
{ 
     initialize(); 

     mainArea.root->rightBro = NULL ; 

     if (mainArea.root->rightBro == NULL) cout << "a" << endl; 
     if (mainArea.root->rightBro == NULL) cout << "b" << endl;  
     return 0; 
} 
+0

[C++指向當函數返回時超出範圍的對象的可能重複 - 爲什麼這會起作用?](http://stackoverflow.com/questions/16591664/c-pointer-to-objects哪位-走出去的範圍外,在功能-回報 - 爲什麼 - 不-TH) – hetepeperfan

回答

9

您正在存儲從initialize以內的局部變量的指針。函數返回後,內存地址不再有效通過指針訪問 - 當程序在main內部解除引用mainArea.root時,程序調用未定義的行爲(UB)。

根據定義,當調用UB時可能發生任何事情。你看到的是某種版本的任何東西。

爲了實際編程的目的,請停止閱讀此處。如果你很好奇爲什麼你特別需要這種類型的行爲,下面是一個解釋:

在實踐中會發生什麼情況是mainArea.root左指向堆棧幀main之後的「未使用」地址。當調用operator<<時,會分配一個新的堆棧幀,它與mainArea.root指向的內存重疊。 operator<<的(堆棧分配的)局部變量覆蓋該存儲器的內容,從main的角度看,導致看到修改後的值。

7

此:

void initialize(){ 
    triangle root; 
    mainArea.root = &root; 
} 

導致未定義的行爲。

變量triangle root;只在該函數正在執行時才存在。一旦函數返回它不再存在。因此mainArea.root指向隨機存儲器,可以重新用於任何事情。

因此,函數退出後mainArea.root的任何使用都是未定義的行爲。這意味着應用程序可以做任何事

-1

這太傻了。看看你的「如果」條件:

if (mainArea.root->rightBro == NULL) cout << "a" << endl; 
if (mainArea.root->rightBro == NULL) cout << "b" << endl; 

條件是相同的,「b」在「a」之後。
:)