C++11 为什么代码会导致分段错误?

C++11 为什么代码会导致分段错误?,c++11,C++11,代码如下: vector<set<int>> sets; set<int> myset{ 3, 5, 8, 2, 10, 9, 7, 15 }; set<int> newSet{ *myset.begin() }; sets.push_back(newSet); set<int>::iterator it = myset.begin(); it++; for (; it != myset.end(); it++) { for (

代码如下:

vector<set<int>> sets;
set<int> myset{ 3, 5, 8, 2, 10, 9, 7, 15 };
set<int> newSet{ *myset.begin() };
sets.push_back(newSet);
set<int>::iterator it = myset.begin();
it++;
for (; it != myset.end(); it++)
{
    for (vector<set<int>>::iterator it1 = sets.begin(); it1 != sets.end(); it1++)
    {
        set<int> newSet1(*it1);      //LINE1
        sets.push_back(newSet1);     //LINE2
        it1->insert(*it);            //LINE3
    }

}
向量集;
集myset{3,5,8,2,10,9,7,15};
设置新闻集{*myset.begin()};
设置。推回(新闻集);
set::iterator it=myset.begin();
it++;
for(;it!=myset.end();it++)
{
对于(向量::迭代器it1=sets.begin();it1!=sets.end();it1++)
{
设置新闻集1(*it1);//行1
set.push_back(newSet1);//第2行
it1->insert(*it);//第3行
}
}
在第一次进入第二个for循环期间,在
LINE2
之后,
it1
变为空,因此
LINE3
导致
分段故障。为什么在
LINE2
之后,
it1
不见了


LINE2
newSet1
复制到向量集中。它会复制整个集合还是只复制
newSet1
的地址?

后推会更改集合,因此它不再可靠。推回将整个条目复制到向量中


通过索引(例如集合[2])访问向量将起作用,但边界未被检查,因此在访问之前,请确保索引在范围内。

让我们看一下代码的子集:

std::vector<T> sets;
for (auto it = sets.begin(); it != sets.end(); it++)
    sets.emplace_back();
std::向量集;
for(auto it=sets.begin();it!=sets.end();it++)
set.emplace_back();
上面的代码显示了未定义的行为,因为我们修改了向量,然后期望
集合
的迭代器仍然有效

特别是,当您执行
insert()
size()==capacity()
时,迭代器将变得无效

关于你的另一个问题: 第2行将新闻集1复制到向量集中。它会复制整套还是只复制newSet1的地址


它将调用
std::set
的复制构造函数,您将获得作为参数传递给
push_back()
调用的集合的副本。

这太令人毛骨悚然了:-(push_-back应该只制作新闻集1的副本。为什么它会销毁新闻集1?它不会。它不会销毁放在向量中的条目。@John它不会销毁
新闻集1
它会使
it1
无效。这是在
push_-back
迭代器
it1
指向错误位置之后,这会导致未定义的在您的情况下,segfault.it1的行为是不可靠的,因为push_back可能会完全改变向量。(它可能会被复制到另一个内存区域以处理较长的数组。即使在STL中,也没有免费的午餐。)我需要的是在迭代向量的过程中更改一个向量。使用迭代器是没有办法的,对吗?使用“for range loop”怎么样?比如“for(auto e:vec){std::set e1(e);vec.puch_back(e1);}”。它能工作吗?