Click here to Skip to main content
15,564,177 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I will explain my problem with example:
I am declaring multimap like that
typedef struct _sAppTime
{
    tstring strProcessID;
    bool bNotChanged;
}sAppTime;

typedef multimap<tstring,sAppTime> MMAPPTIME;
typedef MMAPPTIME::iterator ITMMAPPTIME;


Now I have to erase those value that have bool bNotChanged == true. The code fulfill this requirement is as shown below.
for (itMMAppTime =mmAppTime.begin(); itMMAppTime != mmAppTime.end();itMMAppTime++)
    {
    // you have to do this because iterators are invalidated
        ITMMAPPTIME erase_iter = itMMAppTime++;
       if(erase_iter->second.bNotChanged)
        {
                mmAppTime.erase(erase_iter);
        }
        break;
    }


I check this with insert one value and check. Crash occur because itMMAppTime do not have any valid pointer after erase.
Please help me out ...
Thanks in advance
Posted
Updated 21-Mar-16 5:30am

A few things wrong with your code:
1. Why do you have a break; at the end of the first iteration of the for loop?
2. If I recall correctly ALL iterators are invalidated by an erase, not just the 1 that is getting deleted.
3. Without the break, you would be double incrementing the iterator if an element was deleted

The best way that I have found to do this is
for (itMMAppTime = mmAppTime.begin(); itMMAppTime != mmAppTime.end(); /*nothing here*/) {
	if (erase_iter->second.bNotChanged) {
		itMMAppTime = mmAppTime.erase(itMMAppTime);
	} else {
		++itMMAppTime; //here is the last part of the for loop so we dont increment twice
	}
	//Why was there a break here?
}
 
Share this answer
 
Comments
Sergey Alexandrovich Kryukov 20-Jan-11 10:55am    
Simple (a 5).
ShilpiP 21-Jan-11 0:15am    
Hi Andrew Brock,
Thanks for your reply. Now i understand where i was wrong. :) Here is my code
for (itMMAppTime =mmAppTime.begin(); itMMAppTime != mmAppTime.end();)
{
// you have to do this because iterators are invalidated
ITMMAPPTIME erase_iter = itMMAppTime++;
if(erase_iter->second.bNotChanged)
{
mmAppTime.erase(erase_iter);
}
}
1) Sorry I forgot to remove break, That was just to check that if only one multimap value is there and it is deleted than crash appear or when it check for next iteration.
2)true
3)That is my mistake actually it is incremented twice.
Thank you so much :) You deserve a 5 and your answer is accepted :)
Stephen Hewitt 22-Jan-11 2:24am    
http://www.sgi.com/tech/stl/Multimap.html

"Multimap has the important property that inserting a new element into a multimap does not invalidate iterators that point to existing elements. Erasing an element from a multimap also does not invalidate any iterators, except, of course, for iterators that actually point to the element that is being erased."
Andrew Brock 22-Jan-11 3:37am    
So much for "standard". Thanks.
Stephen Hewitt 22-Jan-11 6:35am    
The standard states that map's (and multimaps, for that matter) should behave as per the text I quoted. Only the iterators of erased elements are invalidated.
Actually this piece of code
C++
#include <map>
#include <iostream>
using namespace std;
struct A
{
  int a;
  bool erase;
  A(int a, bool erase):a(a),erase(erase){}
};
int main()
{
  multimap<string, A> mmap;
  mmap.insert(make_pair<string,A>(string("a1"), A(1,false)));
  mmap.insert(make_pair<string,A>(string("a2"), A(2,true)));
  mmap.insert(make_pair<string,A>(string("a3"), A(3,true)));
  mmap.insert(make_pair<string,A>(string("a4"), A(4,false)));
  for (multimap<string,A>::iterator it = mmap.begin(); it != mmap.end(); it++)
  {
    if (it->second.erase) mmap.erase(it);
  }
  for (multimap<string,A>::iterator it = mmap.begin(); it != mmap.end(); it++)
  {
    cout << it->first << ", " << it->second.a << ", " << it->second.erase << endl;
  }
}


works fine for me.
:)
 
Share this answer
 
v2
Comments
ShilpiP 21-Jan-11 0:17am    
Hi cPallini,
Thanks for your reply. I understand where i was wrong :).
CPallini 21-Jan-11 1:56am    
You are welcome. :-)

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900