Pergunta

O que exatamente é um "assert", ou mais especificamente, como faço para me livrar de um erro. Quando eu criar um vetor de ponteiros para uma classe com membro de dados int x, e, em seguida, faça o seguinte:

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

e executar o programa, recebo nenhum erro até que x é maior do que maxx e eu uso .erase (), em que ponto eu recebo este erro:

Debug Assertion Failed!

Programa: ... Meus Documentos \ Arquivos O.exe: ... incluem \ Linha vetor: 116

Expression: ( "This -> _ Has_container ()", 0)

Para obter informações sobre como seu programa pode causar uma falha de declaração, consulte documentação do Visual C ++ em afirma.

(Pressione Repetir para depurar o aplicativo)

[Abort] [Repetir] [Ignorar]

Além disso, se eu tento usar cout:

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

Eu recebo este erro:

Debug Assertion Failed!

Programa: ... Meus Documentos \ Arquivos O.exe: ... incluem \ Linha vetor: 98

Expression: Vetor iterador não deferencable

Para obter informações sobre como seu programa pode causar uma falha de declaração, consulte documentação do Visual C ++ em afirma.

(Pressione Repetir para depurar o aplicativo)

[Abort] [Repetir] [Ignorar]

Alguém poderia me dizer por que eu não posso usar qualquer um dos dados no vetor, e como corrigi-lo?

TAMBÉM: antiviral_data é um vetor de ponteiros, com um único elemento:

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

Se isso ajuda.

Foi útil?

Solução

A razão mais provável porque você começa a afirmação é que você incrementa I após um apagamento. Tente isto em vez disso:

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

Veja também http://www.cppreference.com/wiki/stl/vector/ apagar , procurar inválida iterators na página.

Outras dicas

Um assert é tipicamente uma expressão inserida por um desenvolvedor para fins de depuração e de controle de erros -. Você colocar diferentes "checagens" no seu código, e tê-lo travar o programa se o cheque não for alcançado

Por exemplo, imagine que você tinha código que ia dividir dois números em algum lugar abaixo da estrada. Mesmo que você sempre esperar uma divisão por não-zero, você colocar a assert antes da divisão em caso de um argumento foi mal calculado. Se o assert falhar, isso significa que em algum lugar até a estrada não foi um fracasso.

As afirmações normalmente aparecem apenas na versão de depuração no código (Se você usar o visual C ++ você pode compilar para debug e release). Ao compilar no modo de versão eliminaria os resultados, é uma idéia muito ruim, já que você ainda teria um erro e provavelmente realmente maus resultados.

Em algum lugar na implementação de Vector (é normal), e speciifcally na linha 98, há uma declaração. Se você tiver acesso ao código do vetor, olhar para ver o que o assert é ou depurar até esse ponto. Isso pode indicar um erro na implementação do vetor, ou no código que chama vetor.

O material que você postou nos dá algumas dicas do que está acontecendo, mas seria útil se você pudesse colar mais do programa, incluindo onde os vetores são definidos.

O problema é com o chamado apagar. Você está interagindo através de um recipiente e, ao mesmo tempo apagando elementos dele. Depois de fazer uma apagar, o seu iterador torna-se inválido. Se você deseja remover elementos de um valor particular de um apagamento uso vector com o algoritmo remove_if. Isto é conhecido como um idioma apagar-remove e explicou muito bem no livro STL eficaz de Scott Meyer. Você também pode se referir a esta pergunta Apagar elementos de um vetor para obter mais informações.

Você já tem um par de boas respostas sobre o que é uma afirmação e por que ele está sendo desencadeada em seu código. Agora, você pode querer considerar o uso de algoritmos de STL para um apagamento duas passagens.

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

A vantagem principal é que apagando elementos em um vector é uma operação cara. Para cada elemento apagado, todos os elementos de que posição para a extremidade do vector tem de ser deslocado uma posição em direcção ao início. O segundo elemento que você apagar irá forçar um segundo movimento de todos os elementos a partir daí ... O STL remove_if algoritmo realiza os movimentos apenas uma vez para a sua posição final retornando um iterador um passado o último elemento não é removido elemento. Então você pode executar um único std :: vector <> :: remove que não vai precisar elementos realocar.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top