Udostępnij za pośrednictwem


Obsługa iteratora debugowania

Biblioteki wykonawczej języka Visual C++ wykrywa sterująca niepoprawne użycie i potwierdza i wyświetla okno dialogowe w czasie wykonywania.Aby włączyć obsługę sterująca debugowania, należy użyć wersji debug biblioteki wykonawczej C do skompilowania programu.Aby uzyskać dodatkowe informacje, zobacz Biblioteka CRT — Funkcje.Aby uzyskać informacje o sposobach używania Iteratory, zobacz Zaznaczone iteratory.

C++ standard opisuje, jak funkcji elementów członkowskich może spowodować Iteratory do kontenera staną się nieprawidłowe.Dwa przykłady to:

  • Usuwanie elementu z kontenera powoduje Iteratory do elementu staną się nieprawidłowe.

  • Zwiększenie rozmiaru wektor (push lub Wstaw) powoduje Iteratory do vector staną się nieprawidłowe.

Przykład

Jeśli kompilacja następujący program w trybie debugowania w czasie wykonywania będzie dochodzić i zakończyć.

/* 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
}

Można użyć symbolu _HAS_ITERATOR_DEBUGGING Aby wyłączyć sterująca debugowania funkcji w kompilacja do debugowania.Następujący program nie dochodzić, ale nadal powoduje zachowanie niezdefiniowane.

Ważna uwagaWażne

Use _ITERATOR_DEBUG_LEVEL to control _HAS_ITERATOR_DEBUGGING.Aby uzyskać dodatkowe informacje, zobacz _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
}
  

Assert występuje również, jeśli użytkownik spróbuje zastosować iterację przed inicjalizacją, jak pokazano poniżej:

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

Poniższy kod powoduje potwierdzenia, ponieważ dwa Iteratory do for_each algorytmu są niezgodne.Algorytmy Sprawdź, czy Iteratory, które są dostarczane do nich odwołuje się tym samym kontenerze.

/* 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; } );
}

Zawiadomienia, że w tym przykładzie użyto wyrażenia lambda [] (int& elem) { elem *= 2; } zamiast functor.Chociaż wybór ten nie ma wpływu na niepowodzenie assert — podobne teoria spowodowałoby awaria — lambdas są to bardzo dobry sposób wykonywać funkcja compact obiektu zadania.Aby uzyskać więcej informacji na temat wyrażeń lambda, zobacz Wyrażenia lambda w języku C++.

Sprawdzanie również sterująca debugowania powoduje, że zmienna sterująca, która jest zadeklarowana w for pętli się poza zakres, kiedy for pętli kończy zakres.

// 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
}

Program Debug: polecenie Iteratory mają-trivial destruktorów.Jeżeli destruktora nie uruchamia się, niezależnie od przyczyny, mogą wystąpić naruszenia praw dostępu i uszkodzenie danych.Spójrzmy na następujący przykład:

/* 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
}

Zobacz też

Informacje

Standardowa biblioteka C++ — Przegląd