请考虑以下情形:
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中的什么?
谢谢…
是的,如果您删除一个迭代器,则该迭代器将获得所谓的 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返回下一个有效迭代器。然后你用
erase
it = T2pS.erase(it)
这就是std::vectorand的工作方式std::deque,但std::mapor 却没有std::set。
std::vector
std::deque
std::map
std::set