C ++ Access Violation Место чтения 0x003AE000 при попытке удаления из вектора

0

Я получаю сообщение об ошибке, когда пытаюсь стирать элемент из вектора, если элемент не установлен логическим. Я попытался найти сеть, но ничего не нашел. Я попытался найти различные способы удаления элементов по индексу x в векторе и нашел функцию: vector.erase(vector.begin() + index)

Поэтому, когда я пытаюсь использовать его в моем цикле for, я получаю доступ к точке доступа, указывающий на строку функции стирания.

Код для цикла, в котором ошибка:

    if (!player.getBullets().empty())
    {
        for (int x = 0; x < player.getBullets().size(); x++)
        {
            //Check for projectiles whos status is dead.
            if (!player.getBullets()[x]->getAlive())
            {
                //Erase the element at position x.
                player.getBullets().erase(player.getBullets().begin() + x);

            }
        }
    }
  • 2
    Вы должны показать намного больше кода, вы должны скомпилировать все предупреждения и информацию об отладке (например, g++ -Wall -g ), и вы должны использовать отладчик (например, gdb ) и показать заданную им обратную трассировку.
  • 3
    Перетаскивание контейнера во время его итерации требует большой заботы и внимания к деталям. Вы заметили, что ваш код не может стереть два последовательных элемента?
Показать ещё 7 комментариев
Теги:
vector

3 ответа

0
Лучший ответ

Это намного проще стереть правильно, если вы используете итератор вместо индекса. Прямое преобразование кода (почти):

vector<Projectile*> bullets = player.getBullets();

for (vector<Projectile*>::iterator x = bullets.begin(); x != bullets.end(); )
{
    //Check for projectiles whos status is dead.
    if (!(*x)->getAlive())
    {
        //Erase the element at position x.
        x = bullets.erase(x);
    }
    else
    {
        ++ x;
    }
}

Обратите внимание, что это работает только с локальной копией вектора. Если вы хотите обновить вектор в самом классе игрока, вам нужно будет изменить getBullets чтобы вернуть ссылку:

vector<Projectile*> &Sprite::getBullets()
{
    return bullets;
}

А затем для цикла:

vector<Projectile*> &bullets = player.getBullets();
  • 0
    Что бы авто было? : S
  • 0
    @sandmaster Это функция C ++ 11 для автоматического определения типа при объявлении переменной. Я использовал ключевое слово auto потому что я не знаю тип вашего вектора, но если вы скажете мне тип вашего вектора, я могу обновить ответ, чтобы избежать auto .
Показать ещё 3 комментария
2

Не изобретайте велосипед, особенно не очень сложный, который может попасть под воду и стены. Используйте готовый вариант:

#include <algorithm>

player.getBullets().erase(
    std::remove_if(player.getBullets().begin(),
                   player.getBullets().end(),
                   [](Projectile * p) -> bool { return !p->getAlive(); }),
    player.getBullets().end());

(Я предполагаю, что Bullet такой же, как decltype(player.getBullets())::value_type, т. decltype(player.getBullets())::value_type Тип элемента контейнера decltype(player.getBullets())::value_type.

  • 0
    Контейнер заполнен объектами класса Projectile; vector <Projectile *>, но remove_if говорит, что оно не определено
  • 0
    @sandmaster: я обновил пост, попробуйте сейчас.
Показать ещё 5 комментариев
0

Хотя цикл недействителен, потому что счетчик x увеличивается, а размер вектора уменьшается, и в результате не весь вектор пересекается, я не вижу причины нарушения доступа. Я думаю, что проблема связана с объектами, хранящимися в векторе.

Ещё вопросы

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