Внезапно элемент вектора стал неинициализированным

0

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

//.час

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. Нет, программа очень простая
Показать ещё 4 комментария
Теги:
initialization
vector

2 ответа

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 Я бы сказал, что это зависит. Иногда вам действительно нужен не обладающий контейнером указателей. Вы просто должны быть уверены, что пуанты переживут контейнер (или, по крайней мере, при любой попытке де-ссылки на содержимое.)
Показать ещё 5 комментариев

Ещё вопросы

Сообщество Overcoder
Наверх
Меню