2011-11-28 51 views
1

此代碼在運行時失敗,而不是在編譯時。我不是C++的專家。 有什麼幫助嗎?C++匿名結構調用失敗

extern void fn(); 

int main(int argc, char** argv) { 
    fn(); 
} 

void fn() 
{ 
    struct Foo{ 
     string name; 
    }*foo; 
    foo->name="sleiman"; 
    cout<<foo->name<<endl; 
} 

爲什麼此代碼在運行時失敗,爲什麼它會成功創建一個靜態實例?

void fn() 
{ 
    struct Foo{ 
     string name; 
    }foo; 
    foo.name="sleiman"; 
    cout<<foo.name<<endl; 
} 

回答

7

foo被製成一個指針,但將不會被初始化,所以當您嘗試訪問命名爲正在讀無效的內存。您將foo初始化爲指向Foo結構體的指針,但不要指示它指向實際對象,因此實際上是鬆散指針。

爲了完成這項工作,您需要使用new關鍵字或其他方法將指針指向實際對象。

+0

新關鍵字不用於初始化指針 –

+0

它是一種在堆棧上創建對象並返回指向該對象的指針的方法,它以某種方式初始化指針。 – DrYap

+0

是的,但我的觀點是,問題不在於他需要初始化指針。問題是他需要實例化一個對象。你可以初始化指針爲null,他仍然會得到一個運行時錯誤。 –

1
struct Foo{ 
    string name; 
}*foo; 

foo只是聲明爲指針,以Foo,但它不指向任何實際的對象。您需要使用新的創建實例,然後才能訪問它的成員。它更像 -

int *ptr; 
(*ptr) = 100; // Can you do this with out ptr pointing to a valid resource ? 

但在另一種情況下,您有自己的實物。

+0

這是真的,但爲什麼它不像往常一樣在C++中顯示垃圾數據 –

+0

行爲是未定義的。不保證有垃圾,並且在運行時也會失敗。 – Mahesh

1

當你創建一個指向X的指針時,你實際上並沒有分配一個X,並且你的指針指向空間的某個地方。您需要分配指針指向X的預先存在的實例,或者使用new X分配新的實例。否則,你正在訪問你不知道它是什麼的內存。這是未定義的行爲,所以任何事情都可能發生。

2

它看起來像在你的第一個例子中,你正在製作一個指向foo的指針。僅僅因爲你製作了一個指向foo的指針並不意味着它實際上指向了一個對象。您必須使用new來創建該對象。試試這個:

void fn() 
{ 
    struct Foo{ 
     string name; 
    }; 
    Foo* foo = new Foo; 
    foo->name="sleiman"; 
    cout<<foo->name<<endl; 
    delete foo; 
} 

確保在完成使用後刪除它。