亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

迭代時從STL集中刪除元素

迭代時從STL集中刪除元素

C++
江戶川亂折騰 2019-10-15 15:49:33
我需要遍歷一組并刪除符合預定義條件的元素。這是我編寫的測試代碼:#include <set>#include <algorithm>void printElement(int value) {    std::cout << value << " ";}int main() {    int initNum[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };    std::set<int> numbers(initNum, initNum + 10);    // print '0 1 2 3 4 5 6 7 8 9'    std::for_each(numbers.begin(), numbers.end(), printElement);    std::set<int>::iterator it = numbers.begin();    // iterate through the set and erase all even numbers    for (; it != numbers.end(); ++it) {        int n = *it;        if (n % 2 == 0) {            // wouldn't invalidate the iterator?            numbers.erase(it);        }    }    // print '1 3 5 7 9'    std::for_each(numbers.begin(), numbers.end(), printElement);    return 0;}最初,我認為在迭代過程中從集合中刪除一個元素會使迭代器無效,并且for循環的增量將具有未定義的行為。即使我執行了此測試代碼,但一切順利,并且我無法解釋原因。我的問題: 這是標準集的已定義行為還是此實現特定?順便說一下,我在ubuntu 10.04(32位版本)上使用gcc 4.3.3。謝謝!
查看完整描述

3 回答

?
泛舟湖上清波郎朗

TA貢獻1818條經驗 獲得超3個贊

如果通過valgrind運行程序,則會看到許多讀取錯誤。換句話說,是的,迭代器是無效的,但是您在示例中很幸運(或者真的很不幸,因為您沒有看到未定義行為的負面影響)。一種解決方案是創建一個臨時迭代器,增加溫度,刪除目標迭代器,然后將目標設置為溫度。例如,重新編寫循環,如下所示:


std::set<int>::iterator it = numbers.begin();                               

std::set<int>::iterator tmp;                                                


// iterate through the set and erase all even numbers                       

for ( ; it != numbers.end(); )                                              

{                                                                           

    int n = *it;                                                            

    if (n % 2 == 0)                                                         

    {                                                                       

        tmp = it;                                                           

        ++tmp;                                                              

        numbers.erase(it);                                                  

        it = tmp;                                                           

    }                                                                       

    else                                                                    

    {                                                                       

        ++it;                                                               

    }                                                                       


查看完整回答
反對 回復 2019-10-15
?
蠱毒傳說

TA貢獻1895條經驗 獲得超3個贊

您誤解了“不確定行為”的含義。未定義的行為并不表示“如果執行此操作,則程序崩潰或產生意外的結果。” 這意味著“如果這樣做,程序可能會崩潰或產生意外結果”,或執行其他任何操作,具體取決于您的編譯器,操作系統,月相等。

如果某件事情執行時沒有崩潰并且表現出預期的效果,則不能證明它不是未定義的行為。它所證明的是,在特定操作系統上使用特定編譯器進行編譯后,其行為恰好符合該特定運行所觀察到的。

從集合中刪除元素會使迭代器對已刪除元素無效。使用無效的迭代器是未定義的行為。碰巧的是,觀察到的行為正是您在此特定情況下想要的;這并不意味著該代碼是正確的。


查看完整回答
反對 回復 2019-10-15
  • 3 回答
  • 0 關注
  • 530 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號