2010-04-16 80 views
3

如果我在堆棧上創建一個對象並將它推入一個列表中,那麼該對象將會丟失該作用域(在下面的示例中,在for循環之外)是否該對象仍然存在於列表中?如果列表仍然包含對象,那麼數據現在無效/可能會損壞?C++堆棧內存仍然有效嗎?

請讓我知道,請解釋的理由..

感謝, JBU

class SomeObject{ 
public: 
    AnotherObject x; 
} 

//And then... 
void someMethod() 
{ 
    std::list<SomeObject> my_list; 
    for(int i = 0; i < SOME_NUMBER; i++) 
    { 
     SomeObject tmp; 
     my_list.push_back(tmp); 

     //after the for loop iteration, tmp loses scope 
    } 

    my_list.front(); //at this point will my_list be full of valid SomeObjects or will the SomeObjects no longer be valid, even if they still point to dirty data 
} 

編輯:所以,如果它是一個std::list<SomeObject*> my_list;而不是列表...在這種情況下它會失效嗎?

+0

您在底部編輯的評論很難分析。你想問什麼? – swestrup 2010-04-16 23:28:50

+0

哎呀,是啊我的意思是問它看起來像這樣它仍然是有效的:std :: list my_list; for(){SomeOjbect tmp; my_list.push_back(&tmp);) – jbu 2010-04-16 23:30:45

+0

如果你這樣做了,你會把這個tmp變量的地址推到列表中,每次迭代之後,tmp被銷燬,相應的列表條目現在指向一個其析構函數叫做* *指向堆棧內存,可能被別的東西替換 如果你要添加指針到這個列表,你需要確保對象的生命期超過列表的內容,否則你的指針可能引用垃圾 – lhumongous 2010-04-17 00:37:06

回答

4

全部容器製作它們存儲的內容的副本。如果要在容器中使用該對象,則需要該對象是可複製和可分配的。

所以是的,vectorlist等全部製作你的對象的副本。


更短的例子:

struct foo {}; 
std::vector<foo> v; 

v.push_back(foo()); 
// makes a copy of the temporary, which dies at the semicolon. 

如果它沒有副本,上面的代碼會很糟糕。


下面的代碼是 OK:

struct foo {}; 
std::vector<foo*> v; 

{ 
    foo f; 
    v.push_back(&f); // fine, but... 
} // ...now f stops existing and... 

v.front(); // ...points to a non-existent object. 
2

是的,它是有效的。 push_back使得copy

+0

那麼如果它是一個std :: list my_list,而不是列表...在這種情況下,它將是無效的嗎? – jbu 2010-04-16 23:23:05

+0

@jbu - 我不確定你在問什麼。一個std :: list。或許是你的意思的代碼示例? – Tim 2010-04-16 23:28:52

+0

std :: list my_list; for(){SomeOjbect tmp; my_list。push_back(&tmp);) – jbu 2010-04-16 23:29:37

6

標準容器製作對象的副本,以便在您的示例中列表仍然正常。

0

與所有STL容器(列表,矢量,地圖,一切),容器讓你加入到容器等什麼副本,只要你添加的不是指針或引用,你就是安全的。

如果你編寫自己的容器,你必須小心你的工作方式,因爲沒有什麼能阻止你編寫一個存儲引用的容器類型 - 這對任何想到它的人來說都是一個令人討厭的驚喜像標準容器一樣工作。