为什么代码导致分段错误?

时间:2014-06-26 23:01:48

标签: 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>>::iterator it1 = sets.begin(); it1 != sets.end(); it1++)
    {
        set<int> newSet1(*it1);      //LINE1
        sets.push_back(newSet1);     //LINE2
        it1->insert(*it);            //LINE3
    }

}

在第一次进入第二个for循环期间,在LINE2之后,it1变为NULL,因此LINE3会导致segmentation fault。为什么在LINE2后,it1消失了?

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

2 个答案:

答案 0 :(得分:1)

push_back更改集,因此it1不再可靠。 push_back将整个条目复制到向量中。

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

答案 1 :(得分:1)

我们来看一下你的代码的一部分:

std::vector<T> sets;
for (auto it = sets.begin(); it != sets.end(); it++)
    sets.emplace_back();

上面的代码展示了未定义的行为,因为我们修改了向量,然后期望sets的迭代器仍然有效。

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

关于您的其他问题:

  

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

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