vector<int> vInt;
vector<int>::iterator itor;
vInt.reserve(5);
for ( int i = 0; i < 5; i++ )
{
vInt.push_back( i );
}
for ( i = 0; i < 5; i++ )
{
cout << vInt.at(i) << '\t';
}
cout << endl;
//开始erase特定元素,比如值为4的元素
//指明删除最后一个,成功
itor = vInt.end()-1;
cout << *itor << endl;
vInt.erase( itor );
但如果换成如下就出现错误:
for ( itor = vInt.begin(); itor != vInt.end(); ++itor )
{
cout << *itor << endl;
if ( *itor == 4 ) //元素为 4 的erase
{
vInt.erase( itor );
}
}
请高手解答,如果你认为是erase后itor位置不定的问题,那么下面的代码为什么又是对的呢?
for ( itor = vInt.begin(); itor != vInt.end(); ++itor )
{
cout << *itor << endl;
if ( *itor == 3 ) //元素为 3 的erase
{
vInt.erase( itor );
}
}
8 个解决方案
#1
是你使用不当了。
//但如果换成如下就出现错误:
这里: for ( itor = vInt.begin(); itor != vInt.end(); ++itor )
{
cout << *itor << endl;
if ( *itor == 4 ) //元素为 4 的erase
{
itor = vInt.erase( itor );
if (itor == vInt.end())
{
break;
}
}
}
//但如果换成如下就出现错误:
这里: for ( itor = vInt.begin(); itor != vInt.end(); ++itor )
{
cout << *itor << endl;
if ( *itor == 4 ) //元素为 4 的erase
{
itor = vInt.erase( itor );
if (itor == vInt.end())
{
break;
}
}
}
#2
你忽视了erase的返回值。就是这样而已。
#3
如果itor为end()后,在下一次的for循环中,
itor != vInt.end()不会做判断吗?一旦判断了,循环自己就会中止才对吧。
为什么还要自己多来一遍做判断?
itor != vInt.end()不会做判断吗?一旦判断了,循环自己就会中止才对吧。
为什么还要自己多来一遍做判断?
#4
itor为end后,下一次判断前会执行++itor,这样就错了。
其实,删除的动作,应该直接使用算法<algorithm>库来完成的。
itor = find(vInt.begin(), vInt.end(), 3);
if(itor != vInt.end())
erase(itor);
其实,删除的动作,应该直接使用算法<algorithm>库来完成的。
itor = find(vInt.begin(), vInt.end(), 3);
if(itor != vInt.end())
erase(itor);
#5
还是stl的基础问题,给earse函数传一个iterator,删除单前的元素.然后做为参数传入的iterator仍然指向当前偏移量的地址,vector容器会此偏移量将后面的所有元素按位向前copy
一位,巧的是你删除的是vector中的最后一个元素,而且用了循环,于是就出问题了。
for ( itor = vInt.begin(); itor != vInt.end(); ++itor )
{
if ( *itor == 4 ) //元素为 4 的erase
{
vInt.erase( itor );
}
}
循环里itor 指向vector[4]时找到该元素,删除vector[4]的内容,而后将vector[4]之后的所有元素前移一位,而vector[4]之后只有vector.end()指针,此指针前移,指向vector[4].此时单个for循环结束,执行++itor (在这儿出事的!!),itor指向vector.end()后面一位去了,此时for的结束判断itor != vInt.end(); 永远为真,itor 一直会++下去,形成死循环。
0 1 2 3 4 vector.end()
↑iter //删除4
0 1 2 3 vector.end() //后面的前移,iter不变,结束for后面的复合语句
↑iter
0 1 2 3 vector.end()
↑iter // iter++,出事了,形成死循环,永远for下去
同理如果你要删除的时vector[3],在删除vector[3]后,vector[4]和vector.end()前移,iter指向的是vector[4],此时单个循环结束,iter++,指向vector.end(),itor != vInt.end()为假,结束循环。
一位,巧的是你删除的是vector中的最后一个元素,而且用了循环,于是就出问题了。
for ( itor = vInt.begin(); itor != vInt.end(); ++itor )
{
if ( *itor == 4 ) //元素为 4 的erase
{
vInt.erase( itor );
}
}
循环里itor 指向vector[4]时找到该元素,删除vector[4]的内容,而后将vector[4]之后的所有元素前移一位,而vector[4]之后只有vector.end()指针,此指针前移,指向vector[4].此时单个for循环结束,执行++itor (在这儿出事的!!),itor指向vector.end()后面一位去了,此时for的结束判断itor != vInt.end(); 永远为真,itor 一直会++下去,形成死循环。
0 1 2 3 4 vector.end()
↑iter //删除4
0 1 2 3 vector.end() //后面的前移,iter不变,结束for后面的复合语句
↑iter
0 1 2 3 vector.end()
↑iter // iter++,出事了,形成死循环,永远for下去
同理如果你要删除的时vector[3],在删除vector[3]后,vector[4]和vector.end()前移,iter指向的是vector[4],此时单个循环结束,iter++,指向vector.end(),itor != vInt.end()为假,结束循环。
#6
一楼正界
进行此步后
if ( *itor == 4 ) //元素为 4 的erase
{
vInt.erase( itor );
}
itor已为vInt.end(),
再执行++itor当然就无法得到这个判断了itor != vInt.end()
进行此步后
if ( *itor == 4 ) //元素为 4 的erase
{
vInt.erase( itor );
}
itor已为vInt.end(),
再执行++itor当然就无法得到这个判断了itor != vInt.end()
#7
我来解释看你满意不满意,vInt.end()是判断它的结束条件,你看看结束条件是怎么定义的(是容器末元素的后一位置),但是你把4删除以后,itor++以后,会跑到末元素的后一位置的后一位置,你可能认为这也是结束条件,不要认为只要容器没内容就是它的结束位置,一定要记住结束位置是它的末元素的后一位置,这样itor!=vInt.end()就是死循环了,我讲的很罗索,不知道你有没有明白,你删除3的话画个图应该知道了吧
#8
你可以写个if语句
if (vInt.end() == vInt.end()+1)
cout << "ddd";
else
cout << "error";
你会发现输出是error,所以你上面那个itor != vInt.end()永远是true,死循环
if (vInt.end() == vInt.end()+1)
cout << "ddd";
else
cout << "error";
你会发现输出是error,所以你上面那个itor != vInt.end()永远是true,死循环
#1
是你使用不当了。
//但如果换成如下就出现错误:
这里: for ( itor = vInt.begin(); itor != vInt.end(); ++itor )
{
cout << *itor << endl;
if ( *itor == 4 ) //元素为 4 的erase
{
itor = vInt.erase( itor );
if (itor == vInt.end())
{
break;
}
}
}
//但如果换成如下就出现错误:
这里: for ( itor = vInt.begin(); itor != vInt.end(); ++itor )
{
cout << *itor << endl;
if ( *itor == 4 ) //元素为 4 的erase
{
itor = vInt.erase( itor );
if (itor == vInt.end())
{
break;
}
}
}
#2
你忽视了erase的返回值。就是这样而已。
#3
如果itor为end()后,在下一次的for循环中,
itor != vInt.end()不会做判断吗?一旦判断了,循环自己就会中止才对吧。
为什么还要自己多来一遍做判断?
itor != vInt.end()不会做判断吗?一旦判断了,循环自己就会中止才对吧。
为什么还要自己多来一遍做判断?
#4
itor为end后,下一次判断前会执行++itor,这样就错了。
其实,删除的动作,应该直接使用算法<algorithm>库来完成的。
itor = find(vInt.begin(), vInt.end(), 3);
if(itor != vInt.end())
erase(itor);
其实,删除的动作,应该直接使用算法<algorithm>库来完成的。
itor = find(vInt.begin(), vInt.end(), 3);
if(itor != vInt.end())
erase(itor);
#5
还是stl的基础问题,给earse函数传一个iterator,删除单前的元素.然后做为参数传入的iterator仍然指向当前偏移量的地址,vector容器会此偏移量将后面的所有元素按位向前copy
一位,巧的是你删除的是vector中的最后一个元素,而且用了循环,于是就出问题了。
for ( itor = vInt.begin(); itor != vInt.end(); ++itor )
{
if ( *itor == 4 ) //元素为 4 的erase
{
vInt.erase( itor );
}
}
循环里itor 指向vector[4]时找到该元素,删除vector[4]的内容,而后将vector[4]之后的所有元素前移一位,而vector[4]之后只有vector.end()指针,此指针前移,指向vector[4].此时单个for循环结束,执行++itor (在这儿出事的!!),itor指向vector.end()后面一位去了,此时for的结束判断itor != vInt.end(); 永远为真,itor 一直会++下去,形成死循环。
0 1 2 3 4 vector.end()
↑iter //删除4
0 1 2 3 vector.end() //后面的前移,iter不变,结束for后面的复合语句
↑iter
0 1 2 3 vector.end()
↑iter // iter++,出事了,形成死循环,永远for下去
同理如果你要删除的时vector[3],在删除vector[3]后,vector[4]和vector.end()前移,iter指向的是vector[4],此时单个循环结束,iter++,指向vector.end(),itor != vInt.end()为假,结束循环。
一位,巧的是你删除的是vector中的最后一个元素,而且用了循环,于是就出问题了。
for ( itor = vInt.begin(); itor != vInt.end(); ++itor )
{
if ( *itor == 4 ) //元素为 4 的erase
{
vInt.erase( itor );
}
}
循环里itor 指向vector[4]时找到该元素,删除vector[4]的内容,而后将vector[4]之后的所有元素前移一位,而vector[4]之后只有vector.end()指针,此指针前移,指向vector[4].此时单个for循环结束,执行++itor (在这儿出事的!!),itor指向vector.end()后面一位去了,此时for的结束判断itor != vInt.end(); 永远为真,itor 一直会++下去,形成死循环。
0 1 2 3 4 vector.end()
↑iter //删除4
0 1 2 3 vector.end() //后面的前移,iter不变,结束for后面的复合语句
↑iter
0 1 2 3 vector.end()
↑iter // iter++,出事了,形成死循环,永远for下去
同理如果你要删除的时vector[3],在删除vector[3]后,vector[4]和vector.end()前移,iter指向的是vector[4],此时单个循环结束,iter++,指向vector.end(),itor != vInt.end()为假,结束循环。
#6
一楼正界
进行此步后
if ( *itor == 4 ) //元素为 4 的erase
{
vInt.erase( itor );
}
itor已为vInt.end(),
再执行++itor当然就无法得到这个判断了itor != vInt.end()
进行此步后
if ( *itor == 4 ) //元素为 4 的erase
{
vInt.erase( itor );
}
itor已为vInt.end(),
再执行++itor当然就无法得到这个判断了itor != vInt.end()
#7
我来解释看你满意不满意,vInt.end()是判断它的结束条件,你看看结束条件是怎么定义的(是容器末元素的后一位置),但是你把4删除以后,itor++以后,会跑到末元素的后一位置的后一位置,你可能认为这也是结束条件,不要认为只要容器没内容就是它的结束位置,一定要记住结束位置是它的末元素的后一位置,这样itor!=vInt.end()就是死循环了,我讲的很罗索,不知道你有没有明白,你删除3的话画个图应该知道了吧
#8
你可以写个if语句
if (vInt.end() == vInt.end()+1)
cout << "ddd";
else
cout << "error";
你会发现输出是error,所以你上面那个itor != vInt.end()永远是true,死循环
if (vInt.end() == vInt.end()+1)
cout << "ddd";
else
cout << "error";
你会发现输出是error,所以你上面那个itor != vInt.end()永远是true,死循环