Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/164.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在C+中使用set的erase属性后获得不同的输出+;STL以几乎相同的方式 在C++中使用set时,我编写了以下代码,它只把元素从1到50推到两个集合S1和S2,在这两个集合之后,我从相同的值迭代到打印值,直到固定的限制。但我无法理解为什么s1和s2的输出不同,因为唯一的区别是s1.erase(it++)被写为{s2.erase(it);it++;}_C++_Stl_Set - Fatal编程技术网

在C+中使用set的erase属性后获得不同的输出+;STL以几乎相同的方式 在C++中使用set时,我编写了以下代码,它只把元素从1到50推到两个集合S1和S2,在这两个集合之后,我从相同的值迭代到打印值,直到固定的限制。但我无法理解为什么s1和s2的输出不同,因为唯一的区别是s1.erase(it++)被写为{s2.erase(it);it++;}

在C+中使用set的erase属性后获得不同的输出+;STL以几乎相同的方式 在C++中使用set时,我编写了以下代码,它只把元素从1到50推到两个集合S1和S2,在这两个集合之后,我从相同的值迭代到打印值,直到固定的限制。但我无法理解为什么s1和s2的输出不同,因为唯一的区别是s1.erase(it++)被写为{s2.erase(it);it++;},c++,stl,set,C++,Stl,Set,简单。这是违法的。一旦删除了该节点,就不允许使用迭代器,甚至不能增加迭代器。你有 不明确的行为是令人讨厌的事情。您的代码可能会崩溃,做一些奇怪的事情,甚至看起来工作正常。最后一个案例是最糟糕的,因为它可能在未来的某个未知点破裂 尽管语言本身没有定义细节,但实际的原因是它是作为二叉树(红黑树)实现的,因此每个节点都包含指向其左、右子节点的指针,可能还有指向其父节点的指针。这些指针用于在树中移动。一旦节点被删除,当您检查这些指针时,就不可能期望它工作 在另一种情况下:s1.擦除(it++)在删除迭代

简单。这是违法的。一旦删除了该节点,就不允许使用迭代器,甚至不能增加迭代器。你有

不明确的行为是令人讨厌的事情。您的代码可能会崩溃,做一些奇怪的事情,甚至看起来工作正常。最后一个案例是最糟糕的,因为它可能在未来的某个未知点破裂

尽管语言本身没有定义细节,但实际的原因是它是作为二叉树(红黑树)实现的,因此每个节点都包含指向其左、右子节点的指针,可能还有指向其父节点的指针。这些指针用于在树中移动。一旦节点被删除,当您检查这些指针时,就不可能期望它工作

在另一种情况下:
s1.擦除(it++)
在删除迭代器之前,先递增迭代器,这样就可以愉快地继续查看容器的其余部分

另一种可能是
it=s2。擦除(it)
,因为
erase
返回下一个迭代器(注意这可能是
end()
)。这是一种更常见的/惯用的模式,仅出于这个原因应该优先考虑,但它也适用于其他容器类型(您的版本不适用)

对于不同类型的容器,迭代器无效规则是不同的,因此请确保仔细阅读。(请注意,这不是真正的官方文档,只有标准,但该网站非常受欢迎)



我还建议您包括您实际使用的文件(例如,
),以及。

#include
——而不是指定标准的include头。请看一看,使用Visual Studio 2015(调试)运行您的代码时,代码在@BobTFish给出的答案指出的行崩溃。因此“输出”甚至没有达到您所显示的程度(这就是未定义行为的全部内容)。旁注:不过,请注意,这适用于集合/映射/列表,但不适用于向量,在向量中,所有指向被删除元素的迭代器都会失效!它应该是
it=s2。擦除(it)请添加一个指向文档的链接:@Raxvan Ha,你比我快-只是想将此添加到我之前的评论中…
it=s2.erase(它)是惯用的。答案中应大力提倡这一点。
#include<bits/stdc++.h>
using namespace std;
set<int> s1,s2;
int main()
{
    int l,r,i;
    for(i=1;i<=50;i++)
    {       s1.insert(i);
            s2.insert(i);
    }
    //scanf("%d%d",&l,&r);
    l=3;r=9;

    printf("Output 1:\n");
    set<int>::iterator it=s1.lower_bound(l);

    while(it!=s1.end() && (*it<=r))
    {
            printf("Before deletion: %d\n",*it);
            s1.erase(it++);
            printf("After deletion: %d\n",*it);
    }

    it=s2.lower_bound(l);
    printf("Output 2\n");
    while(it!=s2.end() && (*it<=r))
    {
            printf("Before deletion: %d\n",*it);
            s2.erase(it);
            it++;
            printf("After deletion: %d\n",*it);
    }
    return 0;
  }
 Output 1:
Before deletion: 3
After deletion: 4  
Before deletion: 4
After deletion: 5
Before deletion: 5
After deletion: 6
Before deletion: 6
After deletion: 7
Before deletion: 7
After deletion: 8
Before deletion: 8 
After deletion: 9
Before deletion: 9
After deletion: 10
Output 2
Before deletion: 3
After deletion: 2
Before deletion: 2
After deletion: 4
Before deletion: 4
After deletion: 6
Before deletion: 6
After deletion: 7
Before deletion: 7
After deletion: 5
Before deletion: 5
After deletion: 8
Before deletion: 8
After deletion: 10
s2.erase(it);
it++;