Deleting items from map while iterating problem

So in my code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
	//triggerEvent is called in engine update every frame.
	void EventManager::triggerEvent(sf::Event* event) {

		if (!listeners_.count(event->type)) return;

		std::map<std::string, listenerFunction>::iterator iterator = listeners_[event->type].begin();

		while (iterator != listeners_[event->type].end()) {

			int listeners_size = listeners_[event->type].size();

			iterator->second(event); //execute listener (inside my custom listener func is unregisterListener called). The unregList will put listener_update in update_listeners_ vector.
			//BTW, the function requires event pointer.

			updateEvents(); //if update_listeners_ is not empty, updateEvents initializes all listeners from update_listeners_ to listeners_[event->type]. listeners_[event->type] is map<string(name), function>. And listeners is map<sf::Event::EventType, std::map<std::string, listenerFunction>>

			//So the error is caused by iterator->second because the function calls unregisterListener which deletes itself while iterating is happening.

			++iterator;

		}

	}


I'm trying to iterate through the whole map to execute listeners (functions). But if an listener calls unregisterListener(name)(deletes an item from map) and deletes itself, the Microsoft Visual C++ Runtime Library will open with error message: map/set iterator not incrementable.
I understand the error, but I don't have idea how to fix it. This is the hardest bug i ever had. I will appreciate any help, and if something is unclear I will answer. Thanks :).
Last edited on
For example,
1
2
3
4
5
6
std::map<T1, T2> map;
//populate map
for (auto i = map.begin(), e = map.end(); i != e;){
    auto current = i++;
    //now you can do whatever you want with current
}
It's not working :/ Expression: map/set iterator not dereferencable
Did you remove the ++iterator; at the end of your loop?
Yes I did.
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
	void EventManager::triggerEvent(sf::Event* event) {

		if (!listeners_.count(event->type)) return;

		//std::map<std::string, listenerFunction>::iterator iterator = listeners_[event->type].begin();

		std::map<std::string, listenerFunction> map = listeners_[event->type];

		for (auto i = map.begin(), e = map.end(); i != e;) {

			auto current = i++;

			i->second(event);

			updateEvents();

		}

		//while (iterator != listeners_[event->type].end()) {

		//	int listeners_size = listeners_[event->type].size();

		//	iterator->second(event); //execute listener (inside my custom listener func is unregisterListener called). The unregList will put listener_update in update_listeners_ vector.
		//	//BTW, the function requires event pointer.

		//	updateEvents(); //if update_listeners_ is not empty, updateEvents initializes all listeners from update_listeners_ to listeners_. listeners_ is map<string(name), function>

		//	//So the error is caused by iterator->second because the function calls unregisterListener which deletes itself while iterating is happening.

		//	++iterator;

		//}

	}
Last edited on
You have to use current inside the loop, not i, since i may be pointing to map.end().
Also, note that line 7 is making a full copy of the map.
This works perfectly! Thank you very much helios :)!
Topic archived. No new replies allowed.