Podpora ladění iterátorů
Knihovna run-time Visual C++ zjistí nesprávné iterátor použití nepodmíněných výrazů a zobrazí dialogové okno v době běhu.Povolit podporu ladění iterátor, musí použít ladicí verze běhové knihovny C kompilace aplikace.Další informace naleznete v tématu Funkce knihovny CRT.Informace o použití iterátorů v Checked – iterátory.
C++ standard popisuje, jak členské funkce může způsobit, že u iterátorů kontejner ztratí platnost.Dvěma příklady jsou:
Mazání z kontejneru prvku způsobí, že u iterátorů prvek ztratí platnost.
Zvětšení vector (push nebo vložit) způsobí, že u iterátorů do vector ztratí platnost.
Příklad
Pokud kompilujete následující program v režimu ladění, za běhu bude vyhodnocení a ukončení.
/* 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
}
Můžete použít symbol _HAS_ITERATOR_DEBUGGING vypnout iterační funkce v sestavení ladící verze ladění.Následující program nebude uplatňovat, ale stále spustí nedefinované chování.
![]() |
---|
Use _ITERATOR_DEBUG_LEVEL to control _HAS_ITERATOR_DEBUGGING.Další informace naleznete v tématu _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 dochází také při pokusu o použití iterátoru před inicializována, jak je znázorněno zde:
/* compile with /EHsc /MDd */
#include <string>
using namespace std;
int main() {
string::iterator i1, i2;
if (i1 == i2)
;
}
Následující příklad kódu způsobí nepravdivých, protože dva iterátory, aby for_each algoritmus nejsou kompatibilní.Algoritmy zkontrolujte, zda jsou iterátory, které jim dodávají odkazování na téže nádobě.
/* 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; } );
}
Všimněte si, že v tomto příkladu lambda výraz [] (int& elem) { elem *= 2; } místo functor.I když tato volba nemá žádný vliv na selhání vyhodnocení – podobné functor způsobí selhání stejné – lambda výrazy jsou velmi užitečným způsobem plnit úkoly compact funkce objektu.Další informace o výrazech lambda naleznete v tématu Výrazy lambda v jazyce C++.
Kontrola také iterátor ladění způsobuje iterační proměnná, která je deklarována v for smyčky se mimo obor, kdy for konce rozsahu opakování.
// 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
}
Ladění u iterátorů mít netriviální destruktory.Pokud destruktor nelze spustit z jakéhokoli důvodu, může dojít k narušení přístupu a poškození dat.Vezměme si jako příklad:
/* 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
}