I have created a vector of sets in my program, and I need to go through each of the sets. In case a specific element is found in the set, I need to add a new set to the vector. However, this gives me a segmentation fault as soon as my array's counter reaches the elements that I inserted later (within the loop). In the following code, switching on list.push_back(cS) gives me a segmentation fault.
int main(void) {
set<int> cS;
vector<set<int> > list;
cS.insert(1);
list.push_back(cS);
cS.insert(2);
list.push_back(cS);
for (int ctr = 0; ctr < list.size(); ctr++)
{
for (set<int>::iterator itr = list[ctr].begin(); itr != list[ctr].end(); itr++)
{
if (*itr == 1 || *itr == 2)
{
cS.clear();
cS.insert(3);
//list.push_back(cS);
}
}
}
for (int ctr = 0; ctr < list.size(); ctr++)
{
for (set<int>::iterator itr = list[ctr].begin(); itr != list[ctr].end(); itr++)
{
cout << *itr << endl;
}
}
return 0;
}
I would be grateful if someone could explain why this gives an error (in gcc).
Thank you for going through my post.
When you push_back
into your vector you invalidate all references to elements in it in the case the vector needs to allocate more memory. In your case the iterator itr
becomes invalid after the push_back
. One solution would be to add the sets to a separate list (vector) and then append them all at once after the for loop:
vector<set<int> > add;
for (int ctr = 0; ctr < list.size(); ctr++)
{
for (set<int>::iterator itr = list[ctr].begin(); itr != list[ctr].end(); itr++)
{
if (*itr == 1 || *itr == 2)
{
cS.clear();
cS.insert(3);
add.push_back(cS);
}
}
}
list.insert(list.end(), add.begin(), add.end());