Sdílet prostřednictvím


Iterační podpory ladění

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.Pro podporu ladění iterátor, musíte použít ladicí verzi běhové knihovny C ke kompilaci aplikace.Další informace naleznete v tématu Funkce knihovny CRT.Informace o použití iterátory, viz Zaškrtnuté iterátory.

C++ standard popisuje, jak členské funkce může způsobit, že u iterátorů kontejner ztratí platnost.Dva příklady jsou:

  • Mazání prvek z kontejneru způsobí, že u iterátorů prvek ztratí platnost.

  • Zvětšení vektorové (push nebo insert) 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 Chcete-li vypnout iterátor ladění funkce v sestavení ladící verze.Následující program nelze uplatnit, ale stále spustí nedefinované chování.

Důležitá poznámkaDůležité

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 také dochází, pokud se pokusíte použít iterátor dříve, než je inicializován, 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 dvě iterátory, chcete-li for_each algoritmu jsou nekompatibilní.Algoritmy zkontrolujte, zda iterátory, které jsou dodávány na ně odkazují 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 tento příklad používá lambda výraz [] (int& elem) { elem *= 2; } místo functor.Přestože je tato volba nijak neovlivňuje při selhání assert – podobné functor způsobí selhání stejné – lambda výrazy jsou velmi vhodný způsob, jak provádět kompaktní funkce objektu úlohy.Další informace o lambda výrazů naleznete v tématu Lambda výrazy v jazyce C++.

Ladění iterátor kontrola také způsobí, že iterační proměnná, která je deklarována v for smyčky je mimo rozsah, 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
}

Viz také

Referenční dokumentace

Standardní knihovna C++ – přehled