Поделиться через


Поддержка отладки итераторов

Библиотека времени выполнения Visual C++ обнаружено неверное использование итераторов и утверждения и отображает диалоговое окно во время выполнения. Чтобы включить отладку поддержка итераторов, необходимо использовать версию отладки библиотеки времени выполнения C — A. чтобы компилировать программы. Для получения дополнительной информации см. Функции библиотеки CRT. Дополнительные сведения об использовании итераторы см. в разделе Проверяемые итераторы.

Стандарт C++ описание функции-члены могут вызвать итераторы в контейнер стать недопустимыми. Пример: 2

  • Физического удаления элемента из контейнера итераторы приводит к элементу стать недопустимым.

  • Увеличение размера vector (внедрения или вставка) вызывает итераторы в vector стать недопустимым.

Пример

Если компилировать следующая программа, в режиме отладки, во время выполнения, утверждение и заканчивается.

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

Можно использовать символ _HAS_ITERATOR_DEBUGGING отключены функции отладки итератора в отладочном построении. Следующая программа не утверждения, но по-прежнему триггеры не задан расширения функциональности.

Важно!

Используйте _ITERATOR_DEBUG_LEVEL к элементу управления _HAS_ITERATOR_DEBUGGING.Для получения дополнительной информации см. _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
}
  

Подтверждение также происходит при попытке использования итератор до его инициализации, как показано ниже, выполните следующие действия.

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

Следующий пример кода вызывает утверждение, поскольку 2 итератора с алгоритмом for_each несовместимы. Алгоритмы проверяют, чтобы определить, ссылаются ли итераторы, предоставляются на них тот же контейнер.

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

Обратите внимание, что в этом примере лямбда-выражение используется [] (int& elem) { elem *= 2; } вместо функтором. Хотя этот вариант имеет подшипник на функтором сбоя — подтверждение, не приводит к те же сбой- лямбда-выражения очень удобный способ выполнения компактные задачи объекта функции. Дополнительные сведения о лямбда-выражениях см. в разделе Лямбда-выражения в C++.

Отладка итератор проверки будет переменной итератора, объявляются, что в цикле for будет из области видимости, область цикла for закончена.

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

Отладка итераторы имеют нетривиальные деструкторы. Если деструктор не выполняется, что по какой-либо причине, нарушения прав доступа и повреждение данных могут возникнуть. Рассмотрим следующий пример.

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

См. также

Ссылки

Общие сведения о стандартной библиотеке C++