Segmentation fault, and I cannot figure it out

When I run this program, I get segmentation fault, I've been spending time for a couple hours but I cannot figure it out.... I need your help!!

This program is for getting rid of multiple map, which already exist.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
  #include <iostream>
#include <map>

using namespace std;

int main()
{
	multimap<string,int> mm;
	mm.insert(pair<string,int>("3",3));
	mm.insert(pair<string,int>("4",4));
	mm.insert(pair<string,int>("4",4));
	mm.insert(pair<string,int>("5",5));
	mm.insert(pair<string,int>("5",5));
	mm.insert(pair<string,int>("6",6));
	mm.insert(pair<string,int>("6",6));
	mm.insert(pair<string,int>("7",7));
	mm.insert(pair<string,int>("8",8));
	mm.insert(pair<string,int>("9",9));
	mm.insert(pair<string,int>("9",9));
	mm.insert(pair<string,int>("10",10));
	




	multimap<string,int>::iterator it2=mm.begin();
	it2++;
	for(multimap<string,int>::iterator it1=mm.begin() ; it1 != mm.end() ; it1++)
	{
		while(it1->second == it2->second)
		{
			mm.erase(it2);
			it2 = it1;
			it2++;
		}
		it2++;
	}

	for(multimap<string,int>::iterator it=mm.begin() ; it != mm.end() ;it++)
	{
		cout << (*it).first << "=>" << (*it).second << endl;
	}

	return 0;
}
Last edited on
The problem is that you cannot use an iterator that is erased.

It will crash when it1 == it2.
I corrected it by using another iterator, but it has the same problem...

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
multimap<string,int>::iterator it2 = mMap.begin();
    it2++;

    multimap<string,int>::iterator save;
    
    for(multimap<string,int>::iterator it1 = mMap.begin(); it1 != mMap.end(); it1++)
    {
        while (it2->second == it1->second)
        {
                save = it2;
                it2++;
                mMap.erase(save);
        }
        it2++;

    }
I wonder if the condition of while loop is available
I figured it out!! I isolated every single code, and could find the while is the problem, and as you said, I corrected the iterator.

1
2
3
4
5
6
7
8
9
10
11
12
13
14

    for(multimap<string,int>::iterator it1 = mMap.begin(); it1 != mMap.end(); it1++)
    {
        if (it2->second == it1->second)
        {
                mMap.erase(it2++);
        }
        else
        {
        it2++;
        }

    }

cannot reproduce
provide a backtrace.
A couple of problems:

- it1 can still be an erased iterator.
- Line 11: if it2 is the last iterator it will go beyond the end.
- Line 14: The same as line 11.
> it1 can still be an erased iterator.
I don't see how. it2 is always one step forward.


`it2' may become mMap.end() and you never check that.
At line 27 if the multimap is empty.
In the last iteration of the loop, whether or not you erase anything.
My answer for:I corrected it by using another iterator, but it has the same problem...I did not see anything after that.

None the less. Line 6 mMap.erase(it2++); looks problematic. Doesn't it increment an erased iterator (and thus works accidentally)?

What happens when the very first element is erased?
None the less. Line 6 mMap.erase(it2++); looks problematic. Doesn't it increment an erased iterator (and thus works accidentally)?

No. This is perfectly legal. The expression it2++ must be evaluated before erase is called, so it2 is incremented prior to the erasure. (A copy of it2 prior to the increment is what erase acts on.)


What happens when the very first element is erased?

Then it2 is equal to mMap.end().

Topic archived. No new replies allowed.