在VS,UNIX / Linux中擦除STL迭代器后会发生什么? [英] What happens to an STL iterator after erasing it in VS, UNIX/Linux?

查看:184
本文介绍了在VS,UNIX / Linux中擦除STL迭代器后会发生什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

请考虑以下情况:

  
map(T,S *)&GetMap //向前解析

map(T,S *)T2pS = GetMap();

for(map(T,S *):: iterator it = T2pS.begin(); it!= T2pS.end(); ++ it)
{
if(it-> second!= NULL)
{
delete it-> second;
it-> second = NULL;
}
T2pS.erase(it);
//在VS2005中,擦除后,我们将在for循环的++ it上崩溃。
//在UNIX,Linux中,这不会崩溃。
} // for



在我看来,在VS2005中, ,迭代器将等于end(),因此在尝试增加它时崩溃。
在这里提供的行为中,编译器之间真的有差别吗?
如果是这样,UNIX / Linux中的erase之后的迭代器将会是什么?



谢谢...

解决方案

是的,如果您删除一个迭代器,该迭代器会得到一个所谓的奇异值,这意味着它不属于任何容器了。你不能增加,减少或读出/写入它了。执行该循环的正确方法是:

  for(map< T,S *> :: iterator it = T2pS。 begin(); it!= T2pS.end(); T2pS.erase(it ++)){
// wilhelmtell在注释中是对的:不需要检查NULL。
//删除NULL指针是一个无操作。
if(it-> second!= NULL){
delete it-> second;
it-> second = NULL;
}
}

对于可能会导致其他迭代器无效的容器迭代器, erase 返回下一个有效的迭代器。然后用

  it = T2pS.erase(it)
pre>

这是如何工作 std :: vector std :: deque ,但不是 std :: map std :: set


Please consider the following scenario:


map(T,S*) & GetMap(); //Forward decleration

map(T, S*) T2pS = GetMap();

for(map(T, S*)::iterator it = T2pS.begin(); it != T2pS.end(); ++it)
{
    if(it->second != NULL)
    {
        delete it->second;
        it->second = NULL;
    }
    T2pS.erase(it);
    //In VS2005, after the erase, we will crash on the ++it of the for loop.
    //In UNIX, Linux, this doesn't crash.
}//for

It seems to me that in VS2005, after the "erase", the iterator will be equal to end(), hence the crash while trying to increment it. Are there really differences between compilers in the behavior presented here? If so, what will the iterator after the "erase" equal to in UNIX/Linux?

Thanks...

解决方案

Yes, if you erase an iterator, that iterator gets a so-called singular value, which means it doesn't belong to any container anymore. You can't increment, decrement or read it out/write to it anymore. The correct way to do that loop is:

for(map<T, S*>::iterator it = T2pS.begin(); it != T2pS.end(); T2pS.erase(it++)) {
    // wilhelmtell in the comments is right: no need to check for NULL. 
    // delete of a NULL pointer is a no-op.
    if(it->second != NULL) {
        delete it->second;
        it->second = NULL;
    }
}

For containers that could invalidate other iterators when you erase one iterator, erase returns the next valid iterator. Then you do it with

it = T2pS.erase(it)

That's how it works for std::vector and std::deque, but not for std::map or std::set.

这篇关于在VS,UNIX / Linux中擦除STL迭代器后会发生什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆