用C++創建的對象:存儲一個指向在方法
我現在有,其中,如果發生的事件的對象被創建的方法,以及一個指針指向該對象被存儲在指針到一個向量該類的對象。但是,由於一旦本地作用域結束,對象就會被銷燬,這是否意味着我存儲到向量中的對象的指針現在爲空或未定義?如果是這樣,是否有任何通用的方法來解決這個問題 - 我假設最好的方法是在堆上分配。
我問這個,因爲當我嘗試訪問矢量和我正在奇怪的行爲的內容做業務,我不知道這可能是原因,或者如果它的東西完全無關。
用C++創建的對象:存儲一個指向在方法
我現在有,其中,如果發生的事件的對象被創建的方法,以及一個指針指向該對象被存儲在指針到一個向量該類的對象。但是,由於一旦本地作用域結束,對象就會被銷燬,這是否意味着我存儲到向量中的對象的指針現在爲空或未定義?如果是這樣,是否有任何通用的方法來解決這個問題 - 我假設最好的方法是在堆上分配。
我問這個,因爲當我嘗試訪問矢量和我正在奇怪的行爲的內容做業務,我不知道這可能是原因,或者如果它的東西完全無關。
如果您存儲指向一個對象,並且該對象被銷燬(如超出範圍),該指針將不能爲null,但如果您嘗試使用它,你會得到不確定的行爲。因此,如果向量中的某個指針指向堆棧分配的對象,並且該對象超出了範圍,則該指針將無法安全使用。特別是,無法判斷一個指針是否指向一個有效的對象;你只需要以這樣的方式編寫你的程序,指針永遠不會曾指向破壞的對象。
要解決這個問題,你可以使用新上堆的對象分配空間。然後它將不會被刪除,直到您刪除它。但是,這需要小心謹慎才能正確使用,因爲您必須確保您的對象不會被過早銷燬(留下另一個「懸掛指針」問題,比如您現在擁有的問題)或太晚(創建內存泄漏)。
要解決是,在C++中常用的方法是用什麼所謂的(具有不同程度的精度)一智能指針。如果你不熟悉C++,那麼你可能不應該擔心這些,但是如果你覺得雄心勃勃(或者因爲內存損壞問題而感到沮喪),請從Boost庫檢查shared_ptr。
是的,我剛剛編輯了我的文章。感謝澄清。 – Anonymous 2009-10-24 00:08:53
您可能還想查看Boost指針容器庫。 – 2009-10-24 00:45:54
這取決於你如何分配的對象。如果將對象分配爲自動變量(即在堆棧中),那麼一旦對象超出作用域,指向該對象的任何指針都將變爲無效,因此,解除引用該指針將導致未定義的行爲。
例如:
Object* pointer;
{
Object myobject;
pointer = &myobject;
}
pointer->doSomething(); // <--- INVALID! myobject is now out of scope
但是,如果你在分配對象上堆,用new
操作,那麼對象仍然有效退出的局部範圍內,即使後。但是,請記住,C++中沒有自動垃圾回收功能,因此您必須記住該對象的delete
,否則您將發生內存泄漏。
如果你有一個局部變量,如int計數器,那麼這將是超出範圍,當你退出的功能,但是,除非你有一個C++有一個垃圾收集器,然後將鼠標指針將在規模,因爲你有一些指向你的對象的全局向量,只要你爲指針做了一個new
。
我還沒有看到,我已經做了new
和我的記憶中,沒有我做任何事情被釋放的情況。
檢查(排名不分先後):
難道你打結構件的對象,其指針你存儲過程中的異常?
在解除引用的容器中是否有空指針?
您使用的是vector
對象時,它超出範圍後? (看起來不太可能,但我仍然要問。)
你正在清理嗎?
這裏有一個樣品沿着幫助您:
void SomeClass::Erase(std::vector<YourType*> &a)
{
for(size_t i = 0; i < a.size(); i++) delete a[i];
a.clear();
}
所以,如果我理解正確的話,你所描述的以下情形:
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.
}
這肯定是不好的。 有兩種主要備選方案:
std::vector<MyClass>
)我一般喜歡當第二選項可能的。這是因爲我不必擔心手動釋放內存,矢量會爲我執行。它通常也更高效。唯一的問題是,我必須確保爲MyClass創建一個拷貝構造函數。這意味着形式爲MyClass(const MyClass& other) { ... }
的構造函數。
如果所討論的對象不是那麼大,選項2可能更可取(因爲在向量重新分配時它將需要被複制)。當然,如果你需要多態行爲,這不是一個選項 – 2009-10-24 00:50:13
如果你描述你的意思是「奇怪的行爲」,你可能會更容易回答你想要的東西 – 2009-10-24 00:21:50