2013-02-01 66 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指出「僅使**失效**迭代器和對擦除元素的引用」。 –