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

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

问题描述

请考虑以下场景:


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 中等于什么?

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?

谢谢...

推荐答案

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

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

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

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)

这对 std::vectorstd::deque 有效,但不适用于 std::mapstd::set.

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天全站免登陆