2009-10-24 40 views
1

用C++創建的對象:存儲一個指向在方法

我現在有,其中,如果發生的事件的對象被創建的方法,以及一個指針指向該對象被存儲在指針到一個向量該類的對象。但是,由於一旦本地作用域結束,對象就會被銷燬,這是否意味着我存儲到向量中的對象的指針現在爲空或未定義?如果是這樣,是否有任何通用的方法來解決這個問題 - 我假設最好的方法是在堆上分配。

我問這個,因爲當我嘗試訪問矢量和我正在奇怪的行爲的內容做業務,我不知道這可能是原因,或者如果它的東西完全無關。

+1

如果你描述你的意思是「奇怪的行爲」,你可能會更容易回答你想要的東西 – 2009-10-24 00:21:50

回答

0

如果您存儲指向一個對象,並且該對象被銷燬(如超出範圍),該指針將不能爲null,但如果您嘗試使用它,你會得到不確定的行爲。因此,如果向量中的某個指針指向堆棧分配的對象,並且該對象超出了範圍,則該指針將無法安全使用。特別是,無法判斷一個指針是否指向一個有效的對象;你只需要以這樣的方式編寫你的程序,指針永遠不會曾指向破壞的對象

要解決這個問題,你可以使用新上堆的對象分配空間。然後它將不會被刪除,直到您刪除它。但是,這需要小心謹慎才能正確使用,因爲您必須確保您的對象不會被過早銷燬(留下另一個「懸掛指針」問題,比如您現在擁有的問題)或太晚(創建內存泄漏)。

要解決,在C++中常用的方法是用什麼所謂的(具有不同程度的精度)一智能指針。如果你不熟悉C++,那麼你可能不應該擔心這些,但是如果你覺得雄心勃勃(或者因爲內存損壞問題而感到沮喪),請從Boost庫檢查shared_ptr

+0

是的,我剛剛編輯了我的文章。感謝澄清。 – Anonymous 2009-10-24 00:08:53

+0

您可能還想查看Boost指針容器庫。 – 2009-10-24 00:45:54

4

這取決於你如何分配的對象。如果將對象分配爲自動變量(即在堆棧中),那麼一旦對象超出作用域,指向該對象的任何指針都將變爲無效,因此,解除引用該指針將導致未定義的行爲。

例如:

Object* pointer; 

{ 
    Object myobject; 
    pointer = &myobject; 
} 

pointer->doSomething(); // <--- INVALID! myobject is now out of scope 

但是,如果你在分配對象上堆,用new操作,那麼對象仍然有效退出的局部範圍內,即使後。但是,請記住,C++中沒有自動垃圾回收功能,因此您必須記住該對象的delete,否則您將發生內存泄漏。

0

如果你有一個局部變量,如int計數器,那麼這將是超出範圍,當你退出的功能,但是,除非你有一個C++有一個垃圾收集器,然後將鼠標指針將在規模,因爲你有一些指向你的對象的全局向量,只要你爲指針做了一個new

我還沒有看到,我已經做了new和我的記憶中,沒有我做任何事情被釋放的情況。

0

檢查(排名不分先後):

  • 難道你打結構件的對象,其指針你存儲過程中的異常?

  • 在解除引用的容器中是否有空指針?

  • 您使用的是vector對象時,它超出範圍後? (看起來不太可能,但我仍然要問。)

  • 你正在清理嗎?

這裏有一個樣品沿着幫助您:

void SomeClass::Erase(std::vector<YourType*> &a) 
{ 
    for(size_t i = 0; i < a.size(); i++) delete a[i]; 
    a.clear(); 
} 
1

所以,如果我理解正確的話,你所描述的以下情形:

class MyClass 
{ 
public: 
    int a; 
    SomeOtherClass b; 
}; 

void Test() 
{ 
    std::vector<MyClass*> b; 
    for (int i=0; i < 10; ++i) 
    { 
     MyClass b; 
     v.push_back(&b); 
    } 
    // now v holds 10 items pointers to strange and scary places. 
} 

這肯定是不好的。 有兩種主要備選方案:

  1. 使用new分配堆上的對象。
  2. 使MyClass的矢量保持實例(即std::vector<MyClass>

我一般喜歡當第二選項可能的。這是因爲我不必擔心手動釋放內存,矢量會爲我執行。它通常也更高效。唯一的問題是,我必須確保爲MyClass創建一個拷貝構造函數。這意味着形式爲MyClass(const MyClass& other) { ... }的構造函數。

+0

如果所討論的對象不是那麼大,選項2可能更可取(因爲在向量重新分配時它將需要被複制)。當然,如果你需要多態行爲,這不是一個選項 – 2009-10-24 00:50:13

相關問題