【问题标题】:Calling erase() on set during iteration在迭代期间在集合上调用 erase()
【发布时间】:2017-06-24 14:28:21
【问题描述】:

我有以下代码:

#include<bits/stdc++.h>
using namespace std;

int main()
{
    set<string> S;
    S.insert("item1");
    S.insert("item2");
    S.insert("item3");
    S.insert("item4");
    int i=0;
    for (set<string>::iterator it = S.begin(); it != S.end(); it++)
        {
            string temp = *it;
            if (i++%2)
            {
                S.erase(temp); // Causes Seg Fault on next iteration
            }
        }
    cout<<"Items Removed\n";
    return 0;
}

上面的代码尝试根据一个简单的条件从集合中删除元素。当使用 mingw-w64 (gcc 7.1.0 x86_64-posix-seh-rev0) 编译时出现分段错误,它在我的系统上失败。

现在我假设这是因为erase() 使当前元素的迭代器无效,从而导致it++ 失败。但我很困惑为什么这在我尝试过的所有在线 IDE 上都能正常工作(Repl.itIdeOneCodeChefCoilruCpp.sh)。想法?

【问题讨论】:

    标签: c++ loops segmentation-fault set mingw


    【解决方案1】:

    正如您所意识到的,std::set::erase 将使擦除元素的迭代器无效。然后代码指向undefined behavior,这意味着一切皆有可能,但没有任何保证;即使它看起来运行良好,但你根本不能依赖它。

    【讨论】:

    • 所以代码可以在这么多不同的在线 IDE 上运行只是巧合?
    • @Erric 是的,这就是 UB 的意思。
    • 我对这种行为很熟悉,但只是在网上看到了这段代码,它在他们的 IDE 上运行,但不是我的,我需要确认。谢谢
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-02-14
    • 2016-02-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-27
    相关资源
    最近更新 更多