У меня есть список (вектор) объектов, которые постоянно отображаются на экране. Во время glutMainLoop у меня есть это обновление glutTimerFunction, которое периодически проверяет, выходит ли объект из границ экрана, и если это так, он удаляет объект. Это дает ошибку сегментации.
Вот класс ->
class bullet
{
private:
public:
void update();
bool check()
{
if(y>=box_len/2)
{
return true;
}
return false;
}
void draw();
};
vector <bullet*> bullets;
Вот функция обновления ->
void update(int value)
{
for( typeof(bullets.begin()) it= bullets.begin(); it!= bullets.end();it++)
{
if((*it)!=NULL)
{
if(*it)->check())
{
delete *it;
bullets.erase(it);
}
}
}
glutTimerFunc(10, update, 0);
}
Зарегистрировать с избытком в main() как
glutTimerFunc(10, update, 0);
Когда удаляемый элемент является последним элементом, итератор становится следующим элементом (bullets.end() в этом случае). Инкремент в конце цикла for приводит к тому, что он становится чем-то недействительным и является причиной segfault.
Восстановленный код ->
void update(int value)
{
for( typeof(bullets.begin()) it= bullets.begin(); it!= bullets.end();it++)
{
if((*it)!=NULL)
{
if(*it)->check())
{
delete *it;
bullets.erase(it);
if(it==bullets.end())
break;
}
}
}
glutTimerFunc(10, update, 0);
}
Я предполагаю, что tr
- это своего рода макрос foreach?
В этом случае удаление элемента из вашего vector
приведет к аннулированию итератора.
Используйте it = bullets.erase(it);
чтобы ваш итератор оставался действительным.
bullet::~bullet
(деструктор)? Также вы можете переписатьbullet::check
как{return y >= box_len/2;}
tr
? Кроме того, похоже, что вам не хватает некоторого кода вокруг этой строки:(*it)->check())
. Предполагается, что это условиеif
?