2013-02-01 67 views
10

检查这个代码:std :: list :: clear invalidate std :: list :: end iterator?

#include "stdafx.h" 
#include <list> 

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    std::list<int> mylist; 
    mylist.push_back(1); 
    std::list<int>::iterator i = mylist.end(); 
    if(i == mylist.end()) 
     printf("end is end\n"); 

    mylist.clear(); 
    if(i == mylist.end()) 
     printf("never get here because Microsoft seems to " 
       "think the iterator is no longer safe.\n"); 

    return 0; 
} 

现在,根据cplusplus.com这不应该是一个问题,而在释放模式,我认为这是很好,并没有真正引起任何问题,但调试变得不可能的这只是保留而不让我继续。任何指针?

+0

有趣。我以为'.end'也是无效的,但文章却说的是相反的。有趣的是,http://ideone.com/Y338N8按预期执行。 +1 –

+0

这是非常有意义的,因为我试图移植到Windows的代码是针对MacOS和Linux编写的。两者都在运行GCC,就像ideone一样。我想这是一个库错误。 –

回答

10

其他答案指出,一般来说,当容器被清除时,不能依赖容器的过去末端迭代器保持有效。然而,列表的过去,一个结束迭代器确实应该仍然有效:

C++ 11 23.3.5.4/3 影响:只的失效的迭代器和引用擦除元素。

过去的最终迭代器不引用任何元素,所以不应该失效。

+0

+1,删除了我的答案。虽然我回想起以前的对话,标准明确支持使用动态分配的哨兵,但这并不意味着'clear()'需要释放它。只需双重检查我们的实现,'clear()'实现为'erase(begin(),end())',并且不会使'end()'迭代器失效。这应该报告给Microsoft,作为其实施中的错误。 –

+2

谢谢,Mike和@DavidRodríguez-dribeas。是的,这是Visual C++ 2012'std :: list'实现中的一个错误。它是Visual C++ 2010的一个回归。请注意,'erase'同样被打破。几个月前我检查了此错误的修复程序,并且该修复程序将出现在Visual C++标准库的下一个发布版本中。修复修复了“擦除”和“清除”。 (这个错误是由客户报告的,但不是通过微软连接,所以我没有一个链接,我可以引用你。) –

+1

报告给微软,但只在VS2013:http://connect.microsoft。 COM/VisualStudio中/反馈/信息/ 808659/STD-列表叔擦除功能于调试模式无效信号端迭代器 – Macker

-2

这实际上是无效的。 迭代器仅在当前状态容器上有效。 添加或删除项目后,迭代器不再有效。

您链接的文章并未说明您所做的事是有效的。清除后他们得到一个新的迭代器。

它在发布代码中没有显示的原因是因为禁用了调试问题。

+0

还有一次:根据问题中的链接:“除了结束迭代器之外,与此容器相关的所有迭代器,引用和指针都是无效的。” –

+0

@meh:不,你错了,最终迭代器*可能会失效 –

+3

“添加或删除项目后,迭代器不再有效。”一般情况并非如此;每个容器都有自己的失效规则,只要引用的元素仍然在列表中,“list”迭代器仍然有效。 –

4

从C++ 11,表100(Sequence容器的要求):

clear() [...]可能违反对过去最结束迭代。

而且std::list当然是一个序列容器模板(23.3.5.1/2):

清单满足所有的容器的要求可逆的容器,(在两个表给出23.2),序列容器,包括大部分可选序列容器要求(23.2.3)和分配器识别容器(表99)。例外是运算符[]和成员函数,这些不提供。这里提供的描述仅适用于列表中未在其中一个表中描述的操作或者存在额外语义信息的操作

+0

补充说明:'end'迭代器是一个奇异值并且保证迭代器稳定性的大多数节点基本容器仅为非奇异值提供了保证。 –

+1

我认为这应该被理解为“有容器,它会使无效的过去最终迭代器和容器不适用”。否则,这将是一个冲突的规范 –

+1

但特定于列表的规范23.3.5.4/3指出“仅使**失效**迭代器和对擦除元素的引用”。 –