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);}”。它能工作吗?