Perché il mio codice vettoriale sta affermando? Che cos'è comunque un'affermazione?

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

  •  03-07-2019
  •  | 
  •  

Domanda

Che cosa è esattamente un " assert " o, più specificamente, come posso eliminare un errore. Quando creo un vettore di puntatori a una classe con il membro di dati int x, e quindi faccio questo:

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

Ed eseguo il programma, non ottengo errori fino a quando x è maggiore di maxx e utilizzo .erase (), a quel punto ottengo questo errore:

  

Asserzione di debug non riuscita!

     

Programma: ... My Documents \ O.exe File:   ... include \ vector Line: 116

     

Espressione:   (& Quot; questo - gt &; & _Has_container () quot;, 0)

     

Per informazioni su come il tuo programma   può causare un errore di asserzione, vedere   la documentazione di Visual C ++ su   afferma.

     

(Premi Riprova per eseguire il debug dell'applicazione)

     

[Abort] [Riprova] [Ignora]

Inoltre, se provo ad usare cout:

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

Ottengo questo errore:

  

Asserzione di debug non riuscita!

     

Programma: ... My Documents \ O.exe File:   ... include \ vector Line: 98

     

Espressione: vettore iteratore no   deferencable

     

Per informazioni su come il tuo programma   può causare un errore di asserzione, vedere   la documentazione di Visual C ++ su   afferma.

     

(Premi Riprova per eseguire il debug dell'applicazione)

     

[Abort] [Riprova] [Ignora]

Qualcuno potrebbe dirmi perché non posso USARE nessuno dei dati nel vettore e come risolverlo?

ANCHE: antiviral_data è un vettore di puntatori, con un singolo elemento:

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

Se questo aiuta.

È stato utile?

Soluzione

Il motivo più probabile per cui si ottiene l'asserzione è che si incrementa I dopo una cancellazione. Prova invece questo:

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

Vedi anche http://www.cppreference.com/wiki/stl/vector/ cancella , cerca iteratori non validi su quella pagina.

Altri suggerimenti

Un'asserzione è in genere un'espressione immessa da uno sviluppatore a scopo di debug e controllo degli errori: si inseriscono diversi " controlli di integrità " nel tuo codice e bloccalo se il controllo non viene raggiunto.

Ad esempio, immagina di avere un codice che avrebbe diviso due numeri da qualche parte lungo la strada. Anche se ti aspetti sempre una divisione diversa da zero, metti in atto prima della divisione nel caso in cui un argomento venisse calcolato male. Se l'asserzione fallisce, significa che da qualche parte lungo la strada c'è stato un fallimento.

Le asserzioni in genere vengono visualizzate solo nella versione di debug nel codice (se si utilizza Visual C ++ è possibile compilare per il debug e il rilascio). Mentre compilare in modalità di rilascio eliminerebbe i risultati, è una pessima idea, dal momento che avresti ancora un errore e probabilmente risultati davvero cattivi.

Da qualche parte nell'implementazione di Vector (è standard), e in particolare nella riga 98, c'è un'affermazione. Se hai accesso al codice vettoriale, cerca di vedere qual è l'asserzione o esegui il debug fino a quel momento. Ciò potrebbe indicare un errore nell'implementazione del vettore o nel codice che chiama il vettore.

Le cose che hai pubblicato ci danno alcuni suggerimenti su ciò che sta succedendo, ma sarebbe utile se tu potessi incollare più del programma, incluso dove sono definiti i vettori.

Il problema riguarda la cancellazione della chiamata. Stai iterando attraverso un contenitore e allo stesso tempo cancellando elementi da esso. Dopo aver effettuato una cancellazione, il tuo iteratore diventa invalido. Se si desidera rimuovere elementi di un determinato valore da un vettore, utilizzare la cancellazione con l'algoritmo remove_if. Questo è noto come un linguaggio di cancellazione-rimozione e spiegato molto bene nel libro Effective STL di Scott Meyer. Puoi anche fare riferimento a questa domanda Cancellazione di elementi da un vettore per ulteriori informazioni.

Hai già un paio di buone risposte su ciò che è un'asserzione e sul perché viene attivato nel tuo codice. Ora, potresti prendere in considerazione l'utilizzo degli algoritmi STL per la cancellazione in due passaggi.

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() );
}

Il vantaggio principale è che cancellare elementi in un vettore è un'operazione costosa. Per ogni elemento cancellato, tutti gli elementi da quella posizione alla fine del vettore devono essere spostati di una posizione verso l'inizio. Il secondo elemento che cancelli forzerà una seconda mossa di tutti gli elementi da lì in poi ... L'algoritmo STL remove_if esegue le mosse solo una volta nella loro posizione finale restituendo un iteratore un passato l'ultimo elemento non rimosso. Quindi puoi eseguire un singolo std :: vector & Lt; & Gt; :: remove che non dovrà spostare gli elementi.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top