Pourquoi mon code de vecteur s'affirme? Qu'est-ce qu'une affirmation de toute façon?

StackOverflow https://stackoverflow.com/questions/817429

  •  03-07-2019
  •  | 
  •  

Question

En quoi consiste exactement & "; assert &" ;;;; ou plus précisément, comment puis-je supprimer une erreur? Lorsque je crée un vecteur de pointeurs vers une classe avec le membre de données int x, puis procédez comme suit:

for(I=antiviral_data.begin();I<antiviral_data.end();I++)
{
    if((*I)->x>maxx)
    {
        antiviral_data.erase(I);
    }
}

Et lancez le programme, je n’obtiens aucune erreur tant que x n’est pas supérieur à maxx et j’utilise .erase (), puis j’obtiens cette erreur:

  

L'assertion de débogage a échoué!

     

Programme: ... Fichier My Documents \ O.exe:   ... include \ vector Line: 116

     

Expression:   (" this - > _Has_container () " 0)

     

Pour plus d'informations sur le fonctionnement de votre programme   peut provoquer un échec d'assertion, voir   la documentation Visual C ++ sur   affirme.

     

(Appuyez sur Réessayer pour déboguer l'application)

     

[Abandonner] [Réessayer] [Ignorer]

De plus, si j'essaie d'utiliser cout:

cout<<(*antiviral_data.begin())->x<<endl;

Je reçois cette erreur:

  

L'assertion de débogage a échoué!

     

Programme: ... Fichier My Documents \ O.exe:   ... include \ vector Line: 98

     

Expression: itérateur de vecteur non   reportable

     

Pour plus d'informations sur le fonctionnement de votre programme   peut provoquer un échec d'assertion, voir   la documentation Visual C ++ sur   affirme.

     

(Appuyez sur Réessayer pour déboguer l'application)

     

[Abandonner] [Réessayer] [Ignorer]

Quelqu'un pourrait-il me dire pourquoi je ne peux pas utiliser les données du vecteur et comment y remédier?

AUSSI: antiviral_data est un vecteur de pointeurs, avec un seul élément:

antiviral_data.push_back(new aX1(player.x,player.y,'>'));

Si cela vous aide.

Était-ce utile?

La solution

La raison la plus probable pour laquelle vous obtenez cette assertion est que vous incrémentez I après un effacement. Essayez ceci à la place:

for(I=antiviral_data.begin();I!=antiviral_data.end();)
{
    if((*I)->x>maxx) I=antiviral_data.erase(I); else ++I;
}

Voir aussi http://www.cppreference.com/wiki/stl/vector/ effacer , recherchez itérateurs non valides sur cette page.

Autres conseils

Une assertion est généralement une expression entrée par un développeur à des fins de débogage et de contrôle d'erreur - vous mettez différentes & "; vérifications de cohérence &"; dans votre code, et le faire planter si la vérification n’est pas effectuée.

Par exemple, imaginez que vous disposiez d'un code qui allait diviser deux nombres ultérieurement. Même si vous vous attendez toujours à une division par une valeur autre que zéro, vous définissez assert avant la division au cas où un argument serait mal calculé. Si l’affirmation échoue, cela signifie qu’il ya un échec quelque part.

Les assertions n'apparaissent généralement que dans la version de débogage du code (si vous utilisez Visual C ++, vous pouvez compiler pour le débogage et la publication). Tandis que la compilation en mode release éliminerait les résultats, c'est une très mauvaise idée, car vous auriez toujours une erreur et probablement de très mauvais résultats.

Quelque part dans l’implémentation de Vector (est-il standard), et plus particulièrement dans la ligne 98, il y a une assertion. Si vous avez accès au code vectoriel, regardez ce qu’est l’assertion ou corrigez-le jusqu’à ce point. Cela pourrait indiquer une erreur dans l'implémentation du vecteur ou dans le code appelant le vecteur.

Les éléments que vous avez publiés nous donnent quelques indices sur ce qui se passe, mais il serait utile de pouvoir en coller davantage sur le programme, y compris l'emplacement où les vecteurs sont définis.

Le problème est avec effacer appel. Vous parcourez un conteneur et en effacez simultanément des éléments. Après avoir effacé, votre itérateur devient invalide. Si vous souhaitez supprimer des éléments d’une valeur particulière d’un vecteur, utilisez effacer avec l’algorithme remove_if. Ceci est connu comme un idiome d'effacement-suppression et très bien expliqué dans le livre Effective STL de Scott Meyer. Vous pouvez également vous référer à cette question Effacer des éléments d'un vecteur pour plus d'informations.

Vous avez déjà quelques bonnes réponses sur ce qu’est une assertion et pourquoi elle est déclenchée dans votre code. Maintenant, vous pouvez envisager d’utiliser des algorithmes STL pour un effacement en deux passes.

namespace {
   struct exceeds : public std::unary_function< TheUnknownType*, bool >
   {
      exceeds_max( int max ) : maxx( max ) {}
      bool operator()( TheUnknownType* data ) {
         return data->x < max;
      } 
   private:
      int maxx;
   };
}
void your_function()
{
   std::vector< TheUnknownType* >::iterator new_end;
   new_end = std::remove_if( antiviral_data.begin(), antiviral_data.end(), exceeds(maxx) );
   antiviral_data.remove( new_end, antiviral_data.end() );
}

Le principal avantage est que l’effacement des éléments d’un vecteur est une opération coûteuse. Pour chaque élément effacé, tous les éléments de cette position à la fin du vecteur doivent être déplacés d'une position vers le début. Le deuxième élément que vous effacerez forcera un deuxième déplacement de tous les éléments à partir de là ... L'algorithme STL remove_if effectue les déplacements une seule fois à leur position finale, renvoyant un itérateur un après le dernier élément non supprimé. Ensuite, vous pouvez effectuer un seul std :: vector & Lt; & Gt; :: remove qui n'aura pas besoin de déplacer des éléments.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top