71 votes

Vérifier si un itérateur est valide

Existe-t-il un moyen de vérifier si un itérateur (qu'il s'agisse d'un vecteur, d'une liste, d'un deque ...) est (toujours) dereferencable, c'est-à-dire qu'il n'a pas été invalidé?

J'utilise try - catch , mais existe-t-il un moyen plus direct de procéder?

Exemple: (qui ne fonctionne pas)

 list<int> l;
for (i = 1; i<10; i++) {
    l.push_back(i * 10);
}

itd = l.begin();
itd++;
if (something) {
    l.erase(itd);
}

/* now, in other place.. check if itd points to somewhere meaningful */
if (itd != l.end())
{
    //  blablabla
}
 

65voto

Jason Govig Points 879

Je suppose que vous voulez dire "est un itérateur valide", qu'il n'a pas été invalidé en raison de modifications apportées au conteneur (par exemple, insertion / effacement dans / à partir d'un vecteur). Dans ce cas, non, vous ne pouvez pas déterminer si un itérateur est déréférencable (en toute sécurité).

26voto

avakar Points 20031

Comme jdehaan dit, si l'itérateur n'était pas entaché de nullité et de points dans un conteneur, vous pouvez vérifier en comparant container.end().

Notez, cependant, que si l'itérateur est singulier , car il n'était pas initialisé ou elle est devenu invalide après une mutation de l'opération sur le conteneur (vecteur de itérateurs sont invalidés lorsque vous augmentez le vecteur de la capacité, par exemple) -- la seule opération que vous êtes autorisé à effectuer est d'affectation. En d'autres termes, vous ne pouvez pas vérifier si l'itérateur est singulier ou pas.

std::vector<int>::iterator iter = vec.begin();
vec.resize(vec.capacity() + 1);
// iter is now singular, you may only perform assignment on it,
// there is no way in general to determine whether it is singular or not

13voto

Terry Mahaffey Points 7368

Non-portable: Oui - dans Visual Studio

Visual Studio STL itérateurs ont une "mise au point" mode de faire exactement cela. Vous ne souhaitez pas activer cette fonction dans navire construit (il est au-dessus), mais utile dans les builds.

Lire à ce sujet sur VC10 ici (ce système peut et le fait de changer à chaque sortie, donc trouver de la documentation spécifique à votre version).

Edit Aussi, je me dois d'ajouter: debug itérateurs dans visual studio sont conçus pour immédiatement exploser lorsque vous les utilisez (au lieu comportement indéfini); à ne pas laisser "l'interrogation" de leur état.

10voto

jdehaan Points 14019

Habituellement, vous le testez en vérifiant s'il est différent de la fin (), comme

 if (it != container.end())
{
   // then dereference
}
 

De plus, le traitement des exceptions pour remplacer la logique est mauvais en termes de conception et de performances. Votre question est très bonne et vaut définitivement un remplacement dans votre code. La gestion des exceptions, comme le nom l'indique, ne doit être utilisée que pour de rares problèmes inattendus.

3voto

daramarak Points 3662

Essayer et attraper n'est pas sûr, vous ne serez pas, ou du moins rarement jeter si votre itérateur est "hors limites".

ce alemjerus dire, un itérateur peut toujours être déréférencés. Peu importe ce que uglyness se trouve en dessous. Il est tout à fait possible d'itérer dans d'autres domaines de la mémoire et de l'écriture à d'autres domaines qui pourraient garder d'autres objets. J'ai été en regardant le code, à regarder les variables de changement pour aucune raison en particulier. C'est un bug qui est vraiment difficile à détecter.

Il est également sage de se rappeler que l'insertion et la suppression d'éléments susceptibles d'invalider toutes les références, les pointeurs et les itérateurs.

Mon meilleur conseil serait de vous garder les itérateurs sous contrôle, et de toujours garder une "fin" itérateur à portée de main pour être en mesure de tester si vous êtes à la "fin de ligne" pour ainsi dire.

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