一尘不染

在VS,UNIX / Linux中删除STL迭代器后,该怎么办?

linux

请考虑以下情形:

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

在我看来,在VS2005中,在“擦除”之后,迭代器将等于end(),因此在尝试增加它时会崩溃。此处介绍的行为之间,编译器之间是否真的存在差异?如果是这样,“擦除”之后的迭代器等于UNIX
/ Linux中的什么?

谢谢…


阅读 214

收藏
2020-06-03

共1个答案

一尘不染

是的,如果您删除一个迭代器,则该迭代器将获得所谓的 singular value
,这意味着它不再属于任何容器。您不能再递增,递减或读出/写入它。进行该循环的正确方法是:

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;
    }
}

对于在擦除一个迭代器时可能使其他迭代器无效的容器,请erase返回下一个有效迭代器。然后你用

it = T2pS.erase(it)

这就是std::vectorand的工作方式std::deque,但std::mapor 却没有std::set

2020-06-03