Obsługa iteratora debugowania
Biblioteka uruchomieniowa języka Visual C++ wykrywa sterująca niepoprawne użycie i deklaracji rozkazujących i wyświetla okno dialogowe w czasie wykonywania.Aby włączyć obsługę sterująca debugowania, należy kliknąć w wersji debugowej biblioteki uruchomieniowej C do kompilowania programu.Aby uzyskać więcej informacji, zobacz Funkcje biblioteki CRT.Aby uzyskać informacje na temat używania Iteratory, zobacz Iteratory zaznaczone.
C++ standard opisuje, jak funkcje składowe może powodować Iteratory do kontenera staną się nieprawidłowe.Dwa przykłady to:
Usuwanie elementu z kontenera powoduje, że Iteratory do elementu staną się nieprawidłowe.
Zwiększenie rozmiaru wektor (wypychanie lub Wstaw) powoduje, że 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ć funkcję w trybie debugowania debugowania sterująca.Następujący program nie, ale nadal powoduje zachowanie niezdefiniowany.
Ważne |
---|
Use _ITERATOR_DEBUG_LEVEL to control _HAS_ITERATOR_DEBUGGING.Aby uzyskać więcej informacji, 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 ma miejsce, gdy nastąpi próba użycia iterację, przed, jak pokazano poniżej:
/* compile with /EHsc /MDd */
#include <string>
using namespace std;
int main() {
string::iterator i1, i2;
if (i1 == i2)
;
}
Poniższy przykład kodu powoduje potwierdzenia, ponieważ dwa Iteratory do for_each algorytm są niezgodne.Algorytmy Sprawdź, czy Iteratory, które są dostarczane do nich odwołuje się do tego samego pojemnika.
/* 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; } );
}
Obwieszczenie, że w tym przykładzie użyto wyrażenia lambda [] (int& elem) { elem *= 2; } zamiast teoria.Mimo, że wybór ten nie ma wpływu na niepowodzenie assert — podobne Teoria spowodowałoby awaria — lambdas są to bardzo dobry sposób, można wykonywać funkcji compact obiektu zadania.Aby uzyskać więcej informacji na temat wyrażeń lambda zobacz Lambda wyrażenia w języku C++.
Sterująca debugowania sprawdzanie również powoduje, że zmienna sterująca, które są zadeklarowane w for pętla się poza zakres, gdy for w pętli zakresu.
// 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ą destruktory nie-jest prosta.Jeśli destruktora nie można uruchomić z jakiegokolwiek powodu, może 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
}