84 votes

itérateur d'effacement de vecteur

J'ai ce code:

 int main()
{
    vector<int> res;
    res.push_back(1);
    vector<int>::iterator it = res.begin();
    for( ; it != res.end(); it++)
    {
        it = res.erase(it);
        //if(it == res.end())
        //  return 0;
    }
}
 

"Un itérateur d'accès aléatoire pointant vers le nouvel emplacement de l'élément qui a suivi le dernier élément effacé par l'appel de fonction, qui est la fin du vecteur si l'opération a effacé le dernier élément de la séquence."

Ce code se bloque mais si j'utilise le if (it == res.end ()), puis retourne cela fonctionne. Comment venir? La boucle for encaisse-t-elle res.end () pour que l'opérateur non égal échoue?

168voto

Pieter Points 9200

res.erase(it) renvoie toujours la prochaine valide itérateur, si vous effacez le dernier élément, il sera le point de .end()

À la fin de la boucle ++it est toujours appelé, de sorte que vous incrément .end() qui n'est pas autorisé.

Une simple vérification pour .end() laisse encore un bug si, comme vous l'avez toujours sauter un élément à chaque itération (it se "incrémenté" par le retour d' .erase(), puis de nouveau par la boucle)

Vous voulez probablement quelque chose comme:

 while (it != res.end()) {
        it = res.erase(it);    
 }

pour effacer chaque élément

(pour être complet: je suppose que c'est un exemple simplifié, si vous souhaitez simplement chaque élément allé sans avoir à effectuer une opération (par exemple, supprimer), vous devez simplement appeler res.clear())

Quand vous avez seulement conditionnellement éléments effacer, vous voulez probablement quelque chose comme

for ( ; it != res.end(); ) {
  if (condition) {
    it = res.erase(it);
  } else {
    ++it;
  }
}

32voto

crazylammer Points 616
 for( ; it != res.end();)
{
    it = res.erase(it);
}
 

ou, plus généralement:

 for( ; it != res.end();)
{
    if (smth)
        it = res.erase(it);
    else
        ++it;
}
 

1voto

Patrice Bernassola Points 7422

L'instruction it ++ se fait à la fin du bloc. Donc, si vous effacez le dernier élément, vous essayez d'incrémenter l'itérateur qui pointe vers une collection vide.

0voto

Les éléments suivants semblent également fonctionner:

 for (vector<int>::iterator it = res.begin(); it != res.end(); it++)
{
  res.erase(it--);
}
 

Vous ne savez pas s'il y a un défaut?

0voto

Benoit Points 35553

N'effacez pas puis n'incrémentez pas l'itérateur. Pas besoin d'incrémenter, si votre vecteur a un nombre impair (ou même, je ne sais pas) d'éléments vous manquerez la fin du vecteur.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X