请考虑以下情形:
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中等于什么?
谢谢...
是的,如果擦除迭代器,那么迭代器会得到一个所谓的奇异值,这意味着它不再属于任何容器.你不能再增加,减少或读出它.执行该循环的正确方法是:
for(map::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::vector
和std::deque
,而不是std::map
或std::set
.