关于vector迭代器的 _Mycont

时间:2022-04-16 04:19:58
在vector文件的代码里找到的这么一段
void _Compat(const _Myt& _Right) const
{ // test for compatible iterator pair
if (this->_Mycont == 0 || this->_Mycont != _Right._Mycont)
{
_DEBUG_ERROR("vector iterators incompatible");
_SCL_SECURE_INVALID_ARGUMENT;
}
}
我的程序就有一个循环在执行迭代器和vector的end()比较时会进入这里,然后就报("vector iterators incompatible")了,我看了下 this->_Mycont是0
那么这个变量到底表示什么呢?什么情况下会变成0?

10 个解决方案

#1


应该是iterator出现问题了.
建议你贴上那段代码

#2


你看看那个变量的变化的地方不就行了?要不你就把代码贴出来~

#3


应该是非法使用空引用造成的,
this->_Mycont 是当前容器大小, _Right._Mycont是引用的那个值、
估计是这样

#4


上面有句错了,应该_Right._Mycont是引用的那个值的索引

#5



原因:
vector 的迭代器类型不兼容,无法进行比较.

分析:
只有来自同一个容器的两个未失效的迭代器才能作较.

对策:
code review


#6


我看了下 this->_Mycont是0 


应该是空引用了吧
这样是不能比较的,如果是个指针还可以的

给个完整代码

#7


vc2005 对于迭代器的匹配是非常严格的,通常这种错误是因为两个不同的迭代器操作同一个 vector,或者是因为迭代器在遍历vector时,vector的链表改变了,就会引发这种错误,比如vector在遍历的途中,别的位置push_back()一个元素,这时迭代器就失效了,导致错误

#8


vector iterators incompatible”

发现引发这个错误的代码如下:



VectorType::iterator it = someVector.begin();
for (; it != someVector.end();)
{
if (*it== value)
{
someVector.erase(it);
}
else
{
++it;
}
}

代码中,在erase操作后,没有修改it就继续循环,在与end()比较时,断言出现。

这里的主要问题是,vector可以用任意方法实现erase,不保证在erase一个元素后,后续的元素一定被移动到这个iterator所引用的位置(地址)。当然,这在几乎所有STL的实现中,都是对的,这也就是以前用VC6编译后运行没有问题的原因。但如果这里用的不是vector,而是list或是map,运行到这里,程序会毫不犹豫的崩溃。

正确的做法是这样的:

STL里所有的容器类的erase实现都会返回一个iterator,这个iterator指向了“当前删除元素的后继元素,或是end()”

因此,在遍历容器的所有元素过程中通过erase删除一个元素后,将erase的返回值赋给迭代变量:

VectorType::iterator it = someVector.begin();
for (; it != someVector.end();)
{
if (*it== value)
{
it = someVector.erase(it);
}
else
{
++it;
}
}

P.S. 可以看出,VS2005带的STL增加了更多的调试特性以避免出现STL的一些错误,有条件的话最好用VS2005的STL。如果没有VS2005,也可以使用STLport,STLport在调试特性上也非常出色。
以上文件引用自“http://hi.baidu.com/adoblog/blog/item/102574233779ba4a925807c0.html”

#9


引用 8 楼 wxh5201314 的回复:
vector iterators incompatible”

发现引发这个错误的代码如下:



VectorType::iterator it = someVector.begin();
for (; it != someVector.end();)
{
if (*it== value)
{
someVector.erase(it);
}
else
{
++it;……


非常感谢。。

#10


mark 

#1


应该是iterator出现问题了.
建议你贴上那段代码

#2


你看看那个变量的变化的地方不就行了?要不你就把代码贴出来~

#3


应该是非法使用空引用造成的,
this->_Mycont 是当前容器大小, _Right._Mycont是引用的那个值、
估计是这样

#4


上面有句错了,应该_Right._Mycont是引用的那个值的索引

#5



原因:
vector 的迭代器类型不兼容,无法进行比较.

分析:
只有来自同一个容器的两个未失效的迭代器才能作较.

对策:
code review


#6


我看了下 this->_Mycont是0 


应该是空引用了吧
这样是不能比较的,如果是个指针还可以的

给个完整代码

#7


vc2005 对于迭代器的匹配是非常严格的,通常这种错误是因为两个不同的迭代器操作同一个 vector,或者是因为迭代器在遍历vector时,vector的链表改变了,就会引发这种错误,比如vector在遍历的途中,别的位置push_back()一个元素,这时迭代器就失效了,导致错误

#8


vector iterators incompatible”

发现引发这个错误的代码如下:



VectorType::iterator it = someVector.begin();
for (; it != someVector.end();)
{
if (*it== value)
{
someVector.erase(it);
}
else
{
++it;
}
}

代码中,在erase操作后,没有修改it就继续循环,在与end()比较时,断言出现。

这里的主要问题是,vector可以用任意方法实现erase,不保证在erase一个元素后,后续的元素一定被移动到这个iterator所引用的位置(地址)。当然,这在几乎所有STL的实现中,都是对的,这也就是以前用VC6编译后运行没有问题的原因。但如果这里用的不是vector,而是list或是map,运行到这里,程序会毫不犹豫的崩溃。

正确的做法是这样的:

STL里所有的容器类的erase实现都会返回一个iterator,这个iterator指向了“当前删除元素的后继元素,或是end()”

因此,在遍历容器的所有元素过程中通过erase删除一个元素后,将erase的返回值赋给迭代变量:

VectorType::iterator it = someVector.begin();
for (; it != someVector.end();)
{
if (*it== value)
{
it = someVector.erase(it);
}
else
{
++it;
}
}

P.S. 可以看出,VS2005带的STL增加了更多的调试特性以避免出现STL的一些错误,有条件的话最好用VS2005的STL。如果没有VS2005,也可以使用STLport,STLport在调试特性上也非常出色。
以上文件引用自“http://hi.baidu.com/adoblog/blog/item/102574233779ba4a925807c0.html”

#9


引用 8 楼 wxh5201314 的回复:
vector iterators incompatible”

发现引发这个错误的代码如下:



VectorType::iterator it = someVector.begin();
for (; it != someVector.end();)
{
if (*it== value)
{
someVector.erase(it);
}
else
{
++it;……


非常感谢。。

#10


mark