2014-02-04 2 views
0

У меня есть следующая часть программы, и я не могу понять, что там происходит. Я генерирую некоторый объект Entity, я вижу, что он хорош и полностью инициализирован, затем я нажимаю этот объект в пустой вектор _goodPopulation и вижу, что наверняка _goodPopulation [0] тот же путь инициализирован, но после того, как управление программой вернется к другому методу в этом class _goodPopulation [0] вдруг стал неинициализированным ... Почему?Внезапно элемент вектора стал неинициализированным

//.h

std::vector<Entity*> _goodPopulation; 
... 

//.cpp

bool ChallengeManager::SelectGoodEnteties(double targetEffectivity) 
{ 
    for (...) 
    { 
     Entity& ent = _entityGenerator->GenerateEntity(); 
     if (ent.GetEffectiveness() > 0) { 
      _goodPopulation.push_back(&Entity(ent)); //coping Entity that was generated 
      Entity* ent2 = _goodPopulation[0];// Just for debugging - Entity object is correct there and fully initialized 
      if (ent.GetEffectiveness() > targetEffectivity) 
      { 
       return true; 
      } 
     } 
    } 

    return false; 
} 

Entity* ChallengeManager::AchiveEffectivity(double targetEffectivity) 
{ 
    while (true) 
    { 
     if (SelectGoodEnteties(targetEffectivity)) { 
      Entity* ent2 = _goodPopulation[0]; // Here _goodPopulation[0] Entity suddenly became uninitialized, all it fields are random numbers 
      return _goodPopulation[_goodPopulation.size() - 1]; 
     } 
    } 
} 
+0

Вы используете многопоточность? –

+0

@rockstartprogrammer. Нет, программа очень проста –

+0

Мне любопытно, вызов '_entityGenerator-> GenerateEntity()', возможно, вы также можете показать функцию GenerateEntity? –

ответ

2
_goodPopulation.push_back(&Entity(ent)); 

В этой строке вы создаете локальную переменную Entity (ent) в стеке и получаете ее адрес. Как только вы выйдете из области видимости, локальная переменная будет уничтожена, а адрес больше недействителен.

Таким образом, вы должны создать новый объект в куче

_goodPopulation.push_back(new Entity(ent)); 

Не забудьте удалить объекты в векторе, когда вы не нуждаетесь в них больше.

for (std::vector<Entity*>::iterator it = _goodPopulation.begin(); it != _goodPopulation.end(); ++it) 
    delete *it; 
4

Вы хранения указателей в вашем векторе, и Вы выдвигаете адрес временной здесь:

_goodPopulation.push_back(&Entity(ent)); 
//       ^^^^^^^^^^^ Temporary Entity object 

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

Это может быть, вы имели в виду

_goodPopulation.push_back(&ent); 

, которая будет работать, если ссылка, возвращенная _entityGenerator->GenerateEntity(); действует достаточно долго.

+0

+1 : Значит, золотое правило никогда не помещается в вектор (любой контейнер)? –

+1

@rockstartprogrammer Я бы сказал, это зависит. Иногда вам действительно нужен контейнер без указателей указателей. Вы просто должны быть уверены, что путники пережили контейнер (или, по крайней мере, любую попытку удалить ссылку на содержимое.) – juanchopanza

+0

@uanchopanza Спасибо! Но _goodPopulation.push_back (& ​​ent) не то, что я имею в виду, у меня есть singleton _entity, что я повторно использую, чтобы не создавать объект каждый раз, и почему здесь я хочу создать новый объект с помощью конструктора копирования –

Смежные вопросы