簡體   English   中英

遞增迭代器,用作std :: multimap擦除范圍的第一個和最后一個

[英]Incrementing iterator that is used as first and last of std::multimap erase range

在運行一個顯示如何從std :: map / multimap刪除范圍的示例時,我注意到以下代碼中的異常行為:

#include <map>
#include <iostream>
#include <string>

int main()
{
    std::multimap<int, std::string> myMap;

    myMap.insert(std::make_pair(3, "three1"));
    myMap.insert(std::make_pair(3, "three2"));
    myMap.insert(std::make_pair(3, "three3"));
    myMap.insert(std::make_pair(45, "fourty five"));
    myMap.insert(std::make_pair(-1, "minus one"));

    std::multimap<int, std::string>::iterator iter = myMap.find(3);
    if (iter != myMap.end()) {
        myMap.erase(iter, iter++); //segmentation fault(!)
    }

    for (auto element : myMap) {
        std::cout << element.first << " -> " << element.second << std::endl;
    }
    return 0;
}

我使用命令g++ --std=c++11 main.cpp構建(我使用g ++ 5.2.1)。

為什么迭代器的增量遞增會導致分段錯誤? 我寧願說這應該創建此迭代器的2個副本,將它們傳遞到擦除方法中,“不刪除任何內容”,就像編碼myMap.erase(iter, iter); 然后增加iter

該段錯誤背后的邏輯是什么?

這是對iter迭代器的無效使用嗎? 如果是這樣-為什么?

BTW。 當我使用預增量myMap.erase(iter, ++iter)時,它會編譯myMap.erase(iter, ++iter)並且在這里它像上面提到的那樣“不擦除”。

未定義對函數調用的參數求值的順序。 所以當你寫:

   myMap.erase(iter, iter++); //segmentation fault(!)

編譯器可以自由選擇是否先評估第二個參數。 當您使用相同的迭代器但有副作用時,您會得到未定義的行為( 請參閱C ++標准的1.9 / 15部分 )。

例如,如果編譯器首先評估第二個參數iter++ ,則遞增的迭代器將用作第一個參數,而第二個參數不遞增iter 結果是:傳遞給擦除()的范圍將是[std::next(iter), iter) -該函數可能會嘗試擦除超出范圍的元素(即UB)。

正如David在評論中建議的那樣,您可以使用iter = myMap.erase(iter) (或使用無副作用的范圍iter = myMap.erase(iter)解決問題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM