디버그 반복기 지원
Visual C++ 런타임 라이브러리가 잘못 된 반복기 사용을 감지 어설션 및 런타임에 대화 상자를 표시 합니다.디버그 반복기 지원 기능을 사용 하려면 프로그램을 컴파일하려면 C 런타임 라이브러리의 디버그 버전을 사용 해야 합니다.자세한 내용은 CRT 라이브러리 기능을 참조하십시오.반복기를 사용 하는 방법에 대 한 내용은 확인 된 반복기.
표준 c + + 멤버 함수 반복기는 컨테이너 유효 하지 않게 될 수 있습니다 방법을 설명 합니다.두 가지 예는 다음과 같습니다.
컨테이너에서 요소 지우기 반복기는 요소를 유효 하지 않게 됩니다.
크기를 늘리면는 벡터 (밀어넣기 또는 삽입) 발생에 대 한 반복기는 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 디버깅 기능은 디버그 빌드에서 반복기를 해제 합니다.다음 프로그램 어설션 하지 않지만 아직 정의 되지 않은 동작을 트리거합니다.
중요 |
---|
Use _ITERATOR_DEBUG_LEVEL to control _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
}
Assert 초기화 하기 전에 다음과 같이 하는 반복기를 사용 하는 경우에 발생 합니다.
/* compile with /EHsc /MDd */
#include <string>
using namespace std;
int main() {
string::iterator i1, i2;
if (i1 == i2)
;
}
다음 코드 예제에서는 어설션을 발생 하 두 반복기는 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
}