Nuta
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować się zalogować lub zmienić katalog.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Iteratory sprawdzane zapewniają, że granice kontenera nie ulegają nadpisaniu. Sprawdzone iteratory mają zastosowanie zarówno do kompilacji wydań, jak i kompilacji debugowania. Aby uzyskać więcej informacji na temat używania iteratorów debugowania podczas kompilowania w trybie debugowania, zobacz Debugowanie obsługi iteratora.
Remarks
Aby uzyskać informacje na temat wyłączania ostrzeżeń generowanych przez zaznaczone iteratory, zobacz _SCL_SECURE_NO_WARNINGS.
Możesz użyć _ITERATOR_DEBUG_LEVEL makra preprocesora, aby włączyć lub wyłączyć funkcję sprawdzanych iteratorów. Jeśli _ITERATOR_DEBUG_LEVEL jest zdefiniowany jako 1 lub 2, niebezpieczne użycie iteratorów powoduje błąd środowiska uruchomieniowego i program zostanie zakończony. Jeśli jest zdefiniowana jako 0, iteratory sprawdzane są wyłączone. Domyślnie wartość parametru _ITERATOR_DEBUG_LEVEL to 0 dla kompilacji wydania i 2 dla kompilacji debugowania.
Important
Starsza dokumentacja i kod źródłowy mogą odwoływać się do makra _SECURE_SCL . Użyj _ITERATOR_DEBUG_LEVEL polecenia , aby kontrolować _SECURE_SCL. Aby uzyskać więcej informacji, zobacz _ITERATOR_DEBUG_LEVEL.
Po _ITERATOR_DEBUG_LEVEL zdefiniowaniu wartości 1 lub 2 te testy iteracyjne są wykonywane:
Wszystkie standardowe iteratory (na przykład
vector::iterator) są sprawdzane.Jeśli iterator danych wyjściowych jest iteratorem sprawdzanym, wywołuje standardowe funkcje biblioteki, takie jak
std::copysprawdzanie zachowania.Jeśli iterator danych wyjściowych jest nieznakowanym iteratorem, wywołania funkcji biblioteki standardowej powodują ostrzeżenia kompilatora.
Następujące funkcje generują błąd środowiska uruchomieniowego, jeśli istnieje dostęp spoza granic kontenera:
Gdy _ITERATOR_DEBUG_LEVEL wartość jest zdefiniowana jako 0:
Wszystkie standardowe iteratory są niezaznaczone. Iteratory mogą wykraczać poza granice kontenera, co prowadzi do niezdefiniowanego zachowania.
Jeśli iterator danych wyjściowych jest iteratorem sprawdzanym, wywołuje standardowe funkcje biblioteki, takie jak
std::copysprawdzanie zachowania.Jeśli iterator danych wyjściowych jest nieznakowanym iteratorem, wywołania funkcji biblioteki standardowej uzyskują niezaznaczone zachowanie.
Sprawdzony iterator odwołuje się do iteratora, który wywołuje invalid_parameter_handler próbę przejścia poza granice kontenera. Aby uzyskać więcej informacji na temat invalid_parameter_handlerprogramu , zobacz Walidacja parametrów.
Adaptery iteracyjne obsługujące iteratory sprawdzane są klasychecked_array_iterator i unchecked_array_iterator klasy.
Examples
Podczas kompilowania przy użyciu _ITERATOR_DEBUG_LEVEL wartości 1 lub 2 wystąpi błąd środowiska uruchomieniowego w przypadku próby uzyskania dostępu do elementu spoza granic kontenera przy użyciu operatora indeksowania niektórych klas.
// checked_iterators_1.cpp
// cl.exe /Zi /MDd /EHsc /W4
#define _ITERATOR_DEBUG_LEVEL 1
#include <vector>
#include <iostream>
using namespace std;
int main()
{
vector<int> v;
v.push_back(67);
int i = v[0];
cout << i << endl;
i = v[1]; //triggers invalid parameter handler
}
Ten program wyświetla komunikat "67", a następnie wyświetla okno dialogowe niepowodzenia asercji z dodatkowymi informacjami na temat błędu.
Podobnie podczas kompilowania przy użyciu _ITERATOR_DEBUG_LEVEL ustawienia na 1 lub 2 wystąpi błąd środowiska uruchomieniowego, jeśli próbujesz uzyskać dostęp do elementu przy użyciu lub frontback w klasach kontenerów, gdy kontener jest pusty.
// checked_iterators_2.cpp
// cl.exe /Zi /MDd /EHsc /W4
#define _ITERATOR_DEBUG_LEVEL 1
#include <vector>
#include <iostream>
using namespace std;
int main()
{
vector<int> v;
int& i = v.front(); // triggers invalid parameter handler
}
Ten program otwiera okno dialogowe niepowodzenia asercji z dodatkowymi informacjami na temat błędu.
Poniższy kod demonstruje różne scenariusze użycia iteratorów wraz z komentarzami dotyczącymi każdego z nich. Domyślnie _ITERATOR_DEBUG_LEVEL w kompilacjach debugowania ustawiono wartość 2 i wartość 0 w kompilacjach retail.
// checked_iterators_3.cpp
// cl.exe /MTd /EHsc /W4
#include <algorithm>
#include <array>
#include <iostream>
#include <iterator>
#include <numeric>
#include <string>
#include <vector>
using namespace std;
template <typename C>
void print(const string& s, const C& c)
{
cout << s;
for (const auto& e : c)
{
cout << e << " ";
}
cout << endl;
}
int main()
{
vector<int> v(16);
iota(v.begin(), v.end(), 0);
print("v: ", v);
// OK: vector::iterator is checked in debug mode
// (i.e. an overrun causes a debug assertion)
vector<int> v2(16);
transform(v.begin(), v.end(), v2.begin(), [](int n) { return n * 2; });
print("v2: ", v2);
// OK: back_insert_iterator is marked as checked in debug mode
// (i.e. an overrun is impossible)
vector<int> v3;
transform(v.begin(), v.end(), back_inserter(v3), [](int n) { return n * 3; });
print("v3: ", v3);
// OK: array::iterator is checked in debug mode
// (i.e. an overrun causes a debug assertion)
array<int, 16> a4;
transform(v.begin(), v.end(), a4.begin(), [](int n) { return n * 4; });
print("a4: ", a4);
// OK: Raw arrays are checked in debug mode
// (an overrun causes a debug assertion)
// NOTE: This applies only when raw arrays are given to C++ Standard Library algorithms!
int a5[16];
transform(v.begin(), v.end(), a5, [](int n) { return n * 5; });
print("a5: ", a5);
// WARNING C4996: Pointers cannot be checked in debug mode
// (an overrun causes undefined behavior)
int a6[16];
int * p6 = a6;
transform(v.begin(), v.end(), p6, [](int n) { return n * 6; });
print("a6: ", a6);
// OK: stdext::checked_array_iterator is checked in debug mode
// (an overrun causes a debug assertion)
int a7[16];
int * p7 = a7;
transform(v.begin(), v.end(), stdext::make_checked_array_iterator(p7, 16), [](int n) { return n * 7; });
print("a7: ", a7);
// WARNING SILENCED: stdext::unchecked_array_iterator is marked as checked in debug mode
// (it performs no checking, so an overrun causes undefined behavior)
int a8[16];
int * p8 = a8;
transform(v.begin(), v.end(), stdext::make_unchecked_array_iterator(p8), [](int n) { return n * 8; });
print("a8: ", a8);
}
Podczas kompilowania tego kodu przy użyciu cl.exe /EHsc /W4 /MTd checked_iterators_3.cpp kompilatora emituje ostrzeżenie, ale kompiluje się bez błędu w pliku wykonywalnym:
algorithm(1026) : warning C4996: 'std::_Transform1': Function call with parameters
that may be unsafe - this call relies on the caller to check that the passed values
are correct. To disable this warning, use -D_SCL_SECURE_NO_WARNINGS. See documentation
on how to use Visual C++ 'Checked Iterators'
Po uruchomieniu w wierszu polecenia plik wykonywalny generuje następujące dane wyjściowe:
v: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
v2: 0 2 4 6 8 10 12 14 16 18 20 22 24 26 28 30
v3: 0 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45
a4: 0 4 8 12 16 20 24 28 32 36 40 44 48 52 56 60
a5: 0 5 10 15 20 25 30 35 40 45 50 55 60 65 70 75
a6: 0 6 12 18 24 30 36 42 48 54 60 66 72 78 84 90
a7: 0 7 14 21 28 35 42 49 56 63 70 77 84 91 98 105
a8: 0 8 16 24 32 40 48 56 64 72 80 88 96 104 112 120
See also
Standardowa biblioteka C++ — przegląd
Obsługa iteratora debugowania