Compartilhar via


Depurar iterador suporte

A biblioteca em tempo de execução do Visual C++ detectar o uso incorreto de iterador, e afirma e exibe uma caixa de diálogo em tempo de execução.Para ativar o suporte de iterador de depuração, você deve usar uma versão de depuração de biblioteca em tempo de execução de energia AC para compilar o programa.Para obter mais informações, consulte Recursos da biblioteca CRT.Para obter informações sobre como usar iteradores, consulte. Iteradores selecionados

O padrão de C++ descreve como as funções de membro podem fazer com que iteradores a eles se tornem um contêiner inválidos.Dois exemplos são:

  • Apagar um elemento de um contêiner faz com que iteradores ao elemento tornem-se inválido.

  • Aumentar o tamanho de vetor ou enviar (inserir) faz com que iteradores em vector tornem-se inválido.

Exemplo

Se você compilar o seguinte programa em modo de depuração, em tempo de execução afirmará e terminará.

/* compile with /EHsc /MDd */
#include <vector>
#include <iostream>

int main() {
   std::vector<int> v ;
   
   v.push_back(10);
   v.push_back(15);
   v.push_back(20);
   
   std::vector<int>::iterator i = v.begin();
   ++i;
   
   std::vector<int>::iterator j = v.end();
   --j;
   
   std::cout<<*j<<'\n';
   
   v.insert(i,25); 
   
   std::cout<<*j<<'\n'; // Using an old iterator after an insert
}

Você pode usar o símbolo _HAS_ITERATOR_DEBUGGING para desativar o recurso de depuração de iterador em uma construção de depuração.O seguinte programa não afirma, mas ainda aciona comportamento indefinido.

Observação importanteImportante

Use _ITERATOR_DEBUG_LEVEL para controlar _HAS_ITERATOR_DEBUGGING.Para obter mais informações, consulte _ITERATOR_DEBUG_LEVEL.

// iterator_debugging.cpp
// compile with: /EHsc /MDd
#define _HAS_ITERATOR_DEBUGGING 0
#include <vector>
#include <iostream>

int main() {
   std::vector<int> v ;
   
   v.push_back(10);
   v.push_back(15);
   v.push_back(20);
   
   std::vector<int>::iterator i = v.begin();
   ++i;
   
   std::vector<int>::iterator j = v.end();
   --j;
   
   std::cout<<*j<<'\n';
   
   v.insert(i,25); 
   
   std::cout<<*j<<'\n'; // Using an old iterator after an insert
}
  

Declarar também ocorre se você tentar usar um como mostrado iterador antes de ser inicializado, aqui:

/* compile with /EHsc /MDd */
#include <string>
using namespace std;
int main() {
   string::iterator i1, i2;
   if (i1 == i2)
      ;
}

O exemplo de código a seguir causa uma declaração porque os dois iteradores ao algoritmo de for_each são incompatíveis.Os algoritmos verificação para determinar se iteradores que eles são fornecidos são referenciando o mesmo recipiente.

/* compile with /EHsc /MDd */
#include <algorithm>
#include <vector>
using namespace std;

int main()
{
    vector<int> v1;
    vector<int> v2;

    v1.push_back(10);
    v1.push_back(20);

    v2.push_back(10);
    v2.push_back(20);

    // The next line will assert because v1 and v2 are
    // incompatible.
    for_each(v1.begin(), v2.end(), [] (int& elem) { elem *= 2; } );
}

Observe que este exemplo usa a expressão [] (int& elem) { elem *= 2; } lambda em vez de um functor.Embora esta opção tem rolamento no functor semelhante de falha - declarar um resultaria a mesma falha - lambdas é uma maneira muito útil para realizar tarefas compactas do objeto de função.Para obter mais informações sobre expressões lambda, consulte Expressões lambda C++.

O iterador de depuração que verifica também faz com que uma variável de iterador que é declarada em um loop de for para ser fora do escopo quando o escopo do loop de for termina.

// debug_iterator.cpp
// compile with: /EHsc /MDd
#include <vector>
#include <iostream>
int main() {
   std::vector<int> v ;
   
   v.push_back(10);
   v.push_back(15);
   v.push_back(20);
   
   for (std::vector<int>::iterator i = v.begin() ; i != v.end(); ++i)
   ;
   --i;   // C2065
}

Iteradores de depuração tem destruidores não triviais.Se um não é destrutor é executado, que é o motivo, as violações de acesso e a corrupção de dados podem ocorrer.Considere o exemplo:

/* compile with: /EHsc /MDd */
#include <vector>
struct base {
   // FIX: uncomment the next line
   // virtual ~base() {}
};

struct derived : base {
   std::vector<int>::iterator m_iter;
   derived( std::vector<int>::iterator iter ) : m_iter( iter ) {}
   ~derived() {}
};

int main() {
   std::vector<int> vect( 10 );
   base * pb = new derived( vect.begin() );
   delete pb;  // doesn't call ~derived()
   // access violation
}

Consulte também

Referência

Visão geral da biblioteca C++ padrão