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 关闭在调试版本的迭代器调试功能。下面的过程不,断言,但仍触发未定义的行为。
![]() |
---|
使用 _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)
;
}
因为对 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; } );
}
请注意此示例使用 lambda 表达式 [] (int& elem) { elem *= 2; } 而不是 functor。尽管此选择与无关断言失败类似的 functor 将生成相同的失败 lambda 是一个非常有用的方式完成、函数对象任务。有关 lambda 表达式的更多信息,请参见 在C++中Lambda表达式。
调试也检查的迭代器会在 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
}