Сотрите несколько элементов в deque C ++ - PullRequest
1 голос
/ 22 апреля 2020

Я пытался стереть несколько элементов в deque в 'while' l oop ниже, но моя программа не дает правильных результатов.

Описание проблемы:

packet_deque содержит 9 Packet объектов - некоторые из них отправляются, а другие не отправляются.

#include <deque> 
#include <iostream> 

class Packet
{
public:
    void set_sent() { sent = true; };
    bool get_sent() { return sent; };
private:
    /* members of Test class */
    bool sent = false;
};

int main()
{ 
    size_t MAX = 9;
    std::deque<Packet> packet_deque(MAX);
    unsigned int i = 0;

    std::deque<Packet>::iterator itr = packet_deque.begin();
    printf("Before erasing sent packets - packet_dequeue size: %d \n", packet_deque.size());
    // initialise the packet queue - creating some sent packets
    for (; itr != packet_deque.end(); ++itr) 
    {
        // set some sent packets
        if (i % 3 == 0) 
        {
            itr->set_sent();
        }
        printf("packet_deque[%d]: %s\n", i, itr->get_sent() ? "sent" : "not_sent");
        ++i;
    }
    printf("\n");

    // erase sent packets in packet_dequeue
    itr = packet_deque.begin();
    while (itr != packet_deque.end())
    {
        if (itr->get_sent())
        {
            // erase the element and do NOT move the pointer
            packet_deque.erase(itr);
        }
        else
        {
            // move to next element
            ++itr;
        }
    }

    printf("After erasing sent packets - packet_dequeue size: %d \n", packet_deque.size());
    for (itr = packet_deque.begin(), i = 0; itr != packet_deque.end(); ++itr) 
    {
        printf("packet_deque[%d]: %s\n", i, itr->get_sent() ? "sent" : "not_sent");
        ++i;
    }
} 

Вывод терминала:

Before erasing sent packets - packet_dequeue size: 9 
packet_deque[0]: sent
packet_deque[1]: not_sent
packet_deque[2]: not_sent
packet_deque[3]: sent
packet_deque[4]: not_sent
packet_deque[5]: not_sent
packet_deque[6]: sent
packet_deque[7]: not_sent
packet_deque[8]: not_sent

After erasing sent packets - packet_dequeue size: 5 
packet_deque[0]: not_sent
packet_deque[1]: not_sent
packet_deque[2]: not_sent
packet_deque[3]: not_sent
packet_deque[4]: not_sent

Вопрос:

Поскольку while l oop просто удаляет sent пакетов, я ожидаю 6 неотправленные пакеты, но получили только 5. Я не мог понять, что пошло не так ... Почему окончательный результат содержит только 5 неотправленных пакетов вместо 6 неотправленных пакетов?

Ответы [ 3 ]

6 голосов
/ 22 апреля 2020

Как правило, все итераторы становятся недействительными после удаления из deque. Ваш код использует недействительный итератор в условии while.

Однако erase возвращает новый действительный итератор, указывающий на элемент сразу после стертого, поэтому правильный код -

itr = packet_deque.erase(itr);
2 голосов
/ 22 апреля 2020

Использовать

itr = packet_deque.erase(itr);

В противном случае текущий итератор недопустим.

0 голосов
/ 22 апреля 2020

Цитировать do c

Все итераторы и ссылки недействительны, если только стертые элементы не находятся в конце или в начале контейнера, в этом случае только итераторы и ссылки на стертые элементы недействительны.

Таким образом, ваш l oop


    while (itr != packet_deque.end())
    {
        if (itr->get_sent())
        {
            // erase the element and do NOT move the pointer
            packet_deque.erase(itr);
        }
        else
        {
            // move to next element
            ++itr;
        }
    }

фактически неверен.

Редактировать: вам следует используйте itr = packet_deque.erase(itr);, чтобы получить действительный итератор.

...