Debug Iterator SupportDebug Iterator Support

Visual C++ 런타임 라이브러리는 부정확한 반복기 사용을 검색하고 런타임에 대화 상자를 어설션하고 표시합니다.The Visual C++ run-time library detects incorrect iterator use, and asserts and displays a dialog box at run time. Debug Iterator Support를 사용하도록 설정하려면 프로그램 컴파일 시 C++ 표준 라이브러리 및 C 런타임 라이브러리의 디버그 버전을 사용해야 합니다.To enable debug iterator support, you must use debug versions of the C++ Standard Library and C Runtime Library to compile your program. 자세한 내용은 CRT 라이브러리 기능을 참조하세요.For more information, see CRT Library Features. 확인된 반복기를 사용하는 방법에 대한 자세한 내용은 확인된 반복기를 참조하세요.For information about how to use checked iterators, see Checked Iterators.

C++ 표준은 멤버 함수로 인해 컨테이너에 대한 반복기가 어떻게 무효화되는지 설명합니다.The C++ standard describes how member functions might cause iterators to a container to become invalid. 다음과 같은 두 가지 예가 있습니다.Two examples are:

  • 컨테이너에서 요소를 지우면 요소에 대한 반복기가 무효화됩니다.Erasing an element from a container causes iterators to the element to become invalid.

  • push 또는 insert를 사용하여 vector의 크기를 줄이면 vector에 대한 반복기가 무효화됩니다.Increasing the size of a vector by using push or insert causes iterators into the vector to become invalid.

잘못 된 반복기Invalid iterators

이 샘플 프로그램을 디버그 모드에서 컴파일하면 이 프로그램이 런타임에 어설션되고 종료됩니다.If you compile this sample program in debug mode, at run time it asserts and terminates.

// iterator_debugging_0.cpp
// compile by using /EHsc /MDd
#include <vector>
#include <iostream>

int main() {
   std::vector<int> v {10, 15, 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
}

_ITERATOR_DEBUG_LEVEL 사용Using _ITERATOR_DEBUG_LEVEL

전처리기 매크로 _ITERATOR_DEBUG_LEVEL을 사용하여 디버그 빌드에서 반복기 디버깅 기능을 끌 수 있습니다.You can use the preprocessor macro _ITERATOR_DEBUG_LEVEL to turn off the iterator debugging feature in a debug build. 이 프로그램은 어설션되지 않지만 정의되지 않은 동작을 계속 트리거합니다.This program does not assert, but still triggers undefined behavior.

// iterator_debugging_1.cpp
// compile by using: /EHsc /MDd
#define _ITERATOR_DEBUG_LEVEL 0
#include <vector>
#include <iostream>

int main() {
    std::vector<int> v {10, 15, 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
}
20
-572662307

초기화 되지 않은 반복기Unitialized iterators

다음과 같이 반복기가 초기화되기 전에 반복기를 사용하려고 하면 어설션이 발생합니다.An assert also occurs if you attempt to use an iterator before it is initialized, as shown here:

// iterator_debugging_2.cpp
// compile by using: /EHsc /MDd
#include <string>
using namespace std;

int main() {
   string::iterator i1, i2;
   if (i1 == i2)
      ;
}

호환 되지 않는 반복기Incompatible iterators

for_each 알고리즘에 대한 두 개의 반복기가 호환되지 않으므로 다음 코드 예제는 어설션을 발생시킵니다.The following code example causes an assertion because the two iterators to the for_each algorithm are incompatible. 알고리즘은 알고리즘에 제공되는 반복기가 같은 컨테이너를 참조하는지 확인합니다.Algorithms check to determine whether the iterators that are supplied to them reference the same container.

// iterator_debugging_3.cpp
// compile by using /EHsc /MDd
#include <algorithm>
#include <vector>
using namespace std;

int main()
{
    vector<int> v1 {10, 20};
    vector<int> v2 {10, 20};

    // The next line asserts because v1 and v2 are
    // incompatible.
    for_each(v1.begin(), v2.end(), [] (int& elem) { elem *= 2; } );
}

이 예제에서는 함수 대신 람다 식 [] (int& elem) { elem *= 2; }를 사용합니다.Notice that this example uses the lambda expression [] (int& elem) { elem *= 2; } instead of a functor. 이 선택은 비슷한 함수가 같은 실패를 일으키는 어설션 실패와 아무런 관련이 없지만 람다는 간단한 함수 개체 작업을 수행하는 매우 유용한 방법입니다.Although this choice has no bearing on the assert failure—a similar functor would cause the same failure—lambdas are a very useful way to accomplish compact function object tasks. 람다 식에 대 한 자세한 내용은 람다 식을 참조 하세요.For more information about lambda expressions, see Lambda Expressions.

범위 밖으로 이동 하는 반복기Iterators going out of scope

또한 디버그 반복기 검사를 수행 하면 루프 for 범위가 종료 될 때 루프에서 선언 된 반복기 변수가 범위를 벗어났습니다 for .Debug iterator checks also cause an iterator variable that's declared in a for loop to be out of scope when the for loop scope ends.

// iterator_debugging_4.cpp
// compile by using: /EHsc /MDd
#include <vector>
#include <iostream>
int main() {
   std::vector<int> v {10, 15, 20};

   for (std::vector<int>::iterator i = v.begin(); i != v.end(); ++i)
      ;   // do nothing
   --i;   // C2065
}

디버그 반복기 용 소멸자Destructors for debug iterators

디버그 반복기에 non-trivial 소멸자가 있습니다.Debug iterators have non-trivial destructors. 소멸자가 실행 되지 않지만 개체의 메모리가 해제 된 경우 액세스 위반 및 데이터 손상이 발생할 수 있습니다.If a destructor does not run but the object's memory is freed, access violations and data corruption might occur. 다음 예를 살펴보세요.Consider this example:

// iterator_debugging_5.cpp
// compile by using: /EHsc /MDd
#include <vector>
struct base {
   // TO 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
}

참고 항목See also

C + + 표준 라이브러리 개요C++ Standard Library Overview