2011-03-14 4 views
4

Le code:error cppcheck: utilisation dangereuse iterator

for(x=abc.begin();x!=abc.end();x++) 
{ 
    if(-----) 
    { 
     ---- 
     abc.erase(x); 
    } 
} 

Et l'erreur est :::
utilisation dangereuse iterator
Après effacement du iterator est invalide si le déréférencement ou comparer avec une autre iterator est invalide .

Quelle est la mauvaise utilisation de l'utilisation de la fonction d'effacement dans le code ci-dessus?

Répondre

4

L'itarator x est invalide après la suppression de la valeur correspondante de abc. Cela devrait corriger:

x = abc.begin(); 

while(x != abc.end()) 
{ 
    if (-----) 
    { 
     ---- 
     x = abc.erase(x); 
     // skipped only to next item 
    } 
    else 
    { // skip only to next item 
     ++x; 
    } 
} 

Les fonctions de modèle erase de conteneurs STL renvoient l'élément suivant, ou end().

Modifier: Merci pour le commentaire par templatetypedef.

+1

Ce correctement évite infirmation, mais attention ... vous allez finir par sauter le 'iterator x' passé les éléments juste après ceux qui sont effacées. – templatetypedef

+0

Ups! Tu as raison. Réponse fixe ... – harper

4

x est un pointeur sur abc. Une fois que vous avez effacé l'élément pointé par x, qu'est-ce que x est supposé pointer et comment fonctionne x++?

5

Vous utilisez x comme variable de contrôle dans la boucle. Comme il est invalidé par erase(), vous ne pouvez pas être sûr qu'il est sûr (ou significatif) de l'incrémenter par la suite en haut de la boucle.

1

Vous n'avez rien dit à propos du conteneur sur lequel vous êtes en train d'itérer. Sur le type du conteneur dépend quels itérateurs sont invalidés. Pour être certain que l'itérateur à l'élément effacé est invalide, mais par exemple dans std::vectortous les éléments itératifs passés seront invalides (y compris end()). Et pour une raison inconnue bien que set::erase invalide seulement l'élément itérateur à effacé, il ne renvoie pas l'itérateur à l'élément suivant.

Donc, avec std::set:

while (x != abc.end()) // end() will not change and even can be stored 
{ 
    if (...) 
     abc.erase(x++); // increments before erasing 
    else 
     ++x; 
}