Dlaczego iterator wektorowy nie jest możliwy do zwiększenia?

Próbuję usunąć zawartość wektora i dostaję błąd-iterator wektorowy nie jest inkrementowalny, dlaczego tak jest?

To jest mój Destruktor:

City::~City()
{
    vector <Base*>::iterator deleteIterator;
    for (deleteIterator = m_basesVector.begin() ; deleteIterator != m_basesVector.end() ; deleteIterator++)
        m_basesVector.erase(deleteIterator);
}  
Dzięki.
Author: Unihedron, 2010-09-23

8 answers

erase unieważnia iterator. Nie możesz już tego używać. Na szczęście dla Ciebie zwraca iterator, którego możesz użyć:

vector <Base*>::iterator deleteIterator = m_basesVector.begin();
while (deleteIterator != m_basesVector.end()) {
    deleteIterator = m_basesVector.erase(deleteIterator);
}

Lub:

m_basesVector.clear();
Czy jesteś odpowiedzialny za uwolnienie pamięci wskazanej przez wskaźniki wektora? Jeśli to jest powód iteracji (a twój prawdziwy program ma więcej kodu, którego nie pokazałeś, co uwalnia te obiekty w pętli), to pamiętaj, że kasowanie od początku wektora jest powolną operacją, ponieważ na każdym kroku, wszystkie elementy wektora muszą być przesunięte w dół o jedno miejsce. Lepiej byłoby zapętlić nad wektorem uwalniając wszystko (wtedy clear() wektor, chociaż jak mówi Mike, nie jest to konieczne, jeśli wektor jest członkiem obiektu, który jest niszczony).
 41
Author: Steve Jessop,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-09-23 14:24:05

Problem polega na tym, że próbujesz użyć iteratora podczas korzystania z funkcji erase (). erase(), push_back(), insert () i inne funkcje modyfikujące unieważniają Iteratory w STL.

Wystarczy użyć funkcji clear ():

City::~City()
{
    m_basesVector.clear();
}  
 11
Author: riwalk,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-09-23 14:13:32

Jeśli próbujesz uwolnić dane w wektorze, zrób to:

for (std::vector<Base*>::iterator it = v.begin(), e = b.end(); it != e; ++it) 
    delete *it;
 3
Author: jmucchiello,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-09-23 14:19:51

Posting to tylko okryć ktoś inny ma ten ten problem i próbuje tego rozwiązania zastanawiasz się, dlaczego to nie działa tutaj jest rzeczywiste rozwiązanie / Wyjaśnienie.

@Steve Jessop-Twój kod jest wadliwy i masz go też tutaj napisane... ( Edytowałem również jego post, aby naprawić problem, gdy tylko zostanie zatwierdzony, zostanie naprawiony w oryginalnym poście)

Http://techsoftcomputing.com/faq/3779252.html

Nie widzę, jak to jest "rozwiązanie" problemu, kiedy to utwórz nowy problem tworząc pętlę nieskończoną w pętli while powinien znajdować się deleteIterator++, tak aby rzeczywiście dotarł do końca wektora.

Również natknąłem się na ten problem i moim rozwiązaniem było wewnątrz pętli while sprawdzanie, czy iterator był równy końcowi lub czy rozmiar wektora był 0 i łamanie przed próbą zwiększenia iteratora.

Ex.

    std::vector<RankPlayer*>::iterator Rank_IT = CurrentPlayers.begin();

    while ( Rank_IT != CurrentPlayers.end() ) 
    {    
        RankPlayer* SelPlayer = (*Rank_IT);

        if( strstr( SelPlayer->GamerTag, this->GamerTag ) != NULL )
        {

            delete[] SelPlayer->PlayerData;
            delete[] SelPlayer;
            Rank_IT = CurrentPlayers.erase( Rank_IT );
        }

        if( Rank_IT == CurrentPlayers.end() || CurrentPlayers.size() == 0 )
        {
            break;
        }
            ++Rank_IT;
    }
 2
Author: Tim Lawrence,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-09-02 14:51:47

Nie ma to związku z pierwotnym problemem zamieszczonym powyżej, ale wyszukiwanie Google na błędzie prowadzi mnie do tej strony, więc zamieszczam go tutaj, aby każdy mógł zobaczyć.

Ostatnio natknąłem się na ten Komunikat o błędzie i wszystkie linie kodów się sprawdziły(nie było "kasowania" ani nic podobnego; wektor był tylko odczytywany).

W końcu zdałem sobie sprawę, że jest problem z zagnieżdżonymi pętlami.

Na przykład rozważ coś takiego:

`for (it=begin(); it!=end();i++)
{
    for (; it!=end();i++)
    {
    }
}`

Kiedy skończysz z zagnieżdżona pętla zwiększy iterator - a następnie pętla rodzica zwiększy go ponownie (!), ostatecznie dokonując kroku iteratora nad end (). Tzn. byłoby to "end()+1", gdyby istniało coś takiego. W związku z tym pętla rodzica wyrzuca ten błąd przy następnym sprawdzaniu.

Aby to obejść, wstawiłem tę linię po pętli potomka:

`if (it == vStringList.end()) --it;`

Brudne, ale działa: d

Wiem, że to może być oczywiste dla niektórych, ale drapałem się nad tym od jakiegoś czasu., lol
 2
Author: Csimbi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-07-26 06:48:31

Każdy iterator wskazujący na usunięty element lub na elementy Po Tym, który został usunięty, zostaje unieważniony po wywołaniu metody kasowania wektora. Metoda Erase zwraca poprawny iterator wskazujący na następny element wektora. Powinieneś użyć tego iteratora, aby kontynuować zapętlanie i nie zwiększać unieważnionego iteratora. Możesz również użyć metody clear, aby usunąć wszystkie elementy w wektorze. Musisz jednak pamiętać, aby wyraźnie odłączyć przydzieloną pamięć dla żywiołów.

 1
Author: naivnomore,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-09-23 14:18:39

Ten kod wycieka całą zawartość wektora-musisz delete *deleteIterator również w pętli. Możesz tego wszystkiego uniknąć, używając Base zamiast Base* jako zawartości vector, wtedy clear() zniszczy je za Ciebie. Lub użyj boost::ptr_vector, który automatyzuje niszczenie, jeśli potrzebujesz surowych wskaźników.

Wywołanie erase() w takiej iteracji forward może być bardzo kosztowne, jeśli vector jest duża, ponieważ każdy element powyżej bieżącej pozycji musi być przesunięty w dół, aby zapewnić, że elementy pozostaną przyległe. Unikaj ręczne kasowanie typu, który proponujesz, z tego i innych powodów.

 1
Author: Steve Townsend,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-09-23 14:25:49

Iteratory wektorowe można zwiększyć, ale jeśli usuniesz elementy, zawartość wektorowa zostanie zmodyfikowana i tym samym iterator jest nieważny.

Tak więc, jeśli usuniesz obiekty, powinieneś użyć zwracanej wartości erase(), która daje następny poprawny iterator.

 0
Author: msteiger,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-09-23 14:13:40