Стереть элемент, повторяющийся в цикле while - PullRequest
0 голосов
/ 24 февраля 2020

Я пытаюсь удалить элементы в deque итерации некоторое время l oop. Однако кажется, что после удаления одного элемента, l oop пропускает следующий элемент. Код следующий

 Example program
#include <iostream>
#include <string>
#include <deque>
#include <algorithm>
using namespace std;

deque<int*> queue;
int main()
{
  int * a1 = new int(0);
  int * a2 = new int(2);
  int * a3 = new int(3);
  int * a4 = new int(4);
  int * a5 = new int(5);
  queue.push_back(a1);
  queue.push_back(a2);
  queue.push_back(a3);
  queue.push_back(a4);
  queue.push_back(a5);

    deque<int * >::iterator it = queue.begin();

    while(it != queue.end())
    {
       std::cout << "Element :" << **it << std::endl;
       //remove all elements are divided by 2
       if((**it&1) == 0)
       {
        deque<int * >::iterator cur = (it+1);
        std::cout << "Erase " << **it << std::endl;
        queue.erase(std::remove(queue.begin(), queue.end(), *it), queue.end());
        delete *it;
        it = cur;
       }
       else
       {
           ++it;
       }
    }
    std::cout << "End" << std::endl;     
}

Выходные данные следующие:

* Элемент: 0 Erase 0

Элемент: 3

Элемент: 4 Erase 4

Конец *

Похоже, что элементы 2 и 5 были пропущены.

1 Ответ

2 голосов
/ 24 февраля 2020

У вас неопределенное поведение, потому что вы разыменовываете недействительный итератор в delete *it;. Чтобы решить вашу непосредственную проблему, вам нужно что-то вроде

int * to_del = *it;
it = queue.erase(it);
delete to_del;

Однако вам также следует избегать использования int *, где достаточно int, и записи циклов, когда что-то применимо в <algorithm>* 1008. *

bool is_even(int i) { return (i % 2) == 0; }

std::deque<int> queue { 0, 2, 3, 4, 5 };
queue.erase(std::remove_if(queue.begin(), queue.end(), is_even), queue.end());
...