Память стека C ++ все еще действительна? - PullRequest
3 голосов
/ 17 апреля 2010

Если я создаю объект в стеке и помещаю его в список, то объект теряет область видимости (вне цикла for в приведенном ниже примере), будет ли объект по-прежнему существовать в списке? Если список все еще содержит объект, эти данные теперь недействительны / возможно повреждены?

Пожалуйста, дайте мне знать, и, пожалуйста, объясните причину ..

Спасибо, 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; вместо списка ... в этом случае это будет недействительным?

Ответы [ 4 ]

6 голосов
/ 17 апреля 2010

Стандартные контейнеры создают копию объекта, поэтому список в вашем примере все еще в порядке.

4 голосов
/ 17 апреля 2010

Все контейнеры делают копию того, что они хранят. Требуется, чтобы объект был конструируемым и назначаемым для копирования, если он будет использоваться в контейнере.

Так что да, vector, list и т. Д. Все делают копию вашего объекта.


Еще более короткий пример:

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

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

Если бы он не сделал копию, приведенный выше код был бы плохим.


Следующий код не ок:

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 голосов
/ 17 апреля 2010

Да, это действительно. push_back делает копию .

0 голосов
/ 17 апреля 2010

Со всеми контейнерами STL (списки, векторы, карты, все, что угодно) контейнеры создают копию того, что вы добавляете в контейнеры, так что, пока то, что вы добавляете, не является указателем или ссылкой, вы в безопасности.

Если вы пишете свои собственные контейнеры, вы должны быть осторожны, как вы делаете вещи, так как ничто не мешает вам написать тип контейнера, который хранит ссылки - это было бы просто неприятным сюрпризом для тех, кто думал, что это работает как стандартный контейнер.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...