John
John

Reputation: 193

why the code cause segmentation fault?

Below is the code:

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
    }

}

During the first time entering the second for loop, after LINE2, it1 becomes a NULL, so LINE3 causes segmentation fault. Why after LINE2, it1 is gone?

LINE2 copies newSet1 into the vector sets. Will it copy the whole set or just the address of newSet1?

Upvotes: 0

Views: 53

Answers (2)

Jiminion
Jiminion

Reputation: 5168

The push_back changes sets, so it1 is no longer reliable. A push_back copies the entire entry into the vector.

Accessing the vector via an index ( e.g., sets[2] ) will work, but bounds are not checked, so be sure the index is within range before accessing.

Upvotes: 1

Bill Lynch
Bill Lynch

Reputation: 81926

Let's take a subset of your code:

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

The above code exhibits undefined behavior because we modify the vector, and then expect that the iterators to sets are still valid.

In particular, the iterators will become invalid when you perform an insert() and size() == capacity().

About your other question:

LINE2 copies newSet1 into the vector sets. Will it copy the whole set or just the address of newSet1?

It will call the copy constructor of std::set<T> and you will get a copy of the set that you passed as an argument to the push_back() call.

Upvotes: 1

Related Questions