std::vector::erase, weiter iterieren?

FBIagent

Erfahrenes Mitglied
Guten Abend,

ich iteriere über ein std::vector Objekt.

C++:
			// interacting with clients
			iter = Server->m_Clients.begin();
			for ( ;iter != Server->m_Clients.end();++ iter ) {
				ClErr = false;

				if ( FD_ISSET( (*iter)->GetSock(), &ExceptFds ) ) {
					ClErr = true;
					(*iter)->OnForceDisconnect();
					(*iter)->OnDisconnect();
				} else {
					if ( FD_ISSET( (*iter)->GetSock(), &ReadFds ) ) {
						Interacted = recv( (*iter)->GetSock(), Buffer, 65537, 0 );
						if ( Interacted == SOCKET_ERROR ) {
							ClErr = true;
							(*iter)->OnForceDisconnect();
							(*iter)->OnDisconnect();
						} else if ( Interacted == 0 ) {
							ClErr = true;
							(*iter)->OnDisconnect();
						} else {
							(*iter)->m_ReadBuffer.insert( (*iter)->m_ReadBuffer.end(), Buffer, Buffer + Interacted );
							(*iter)->OnData();
						}
					}
					if ( !ClErr && FD_ISSET( (*iter)->GetSock(), &WriteFds ) ) {
						Interacted = (*iter)->m_WriteBuffer.size() > 65537 ? 65537 : (*iter)->m_WriteBuffer.size();
						std::copy( (*iter)->m_WriteBuffer.begin(), (*iter)->m_WriteBuffer.begin() + Interacted, Buffer );

						Interacted = send( (*iter)->GetSock(), Buffer, Interacted, 0 );
						if ( Interacted == SOCKET_ERROR ) {
							ClErr = true;
							(*iter)->OnForceDisconnect();
							(*iter)->OnDisconnect();
						} else {
							(*iter)->m_WriteBuffer.erase( (*iter)->m_WriteBuffer.begin(), (*iter)->m_WriteBuffer.begin() + Interacted );
						}
					}
				}

				// really?
				/*FD_CLR( iter->m_Sock, &ExceptFds );
				FD_CLR( iter->m_Sock, &WriteFds );
				FD_CLR( iter->m_Sock, &ReadFds );*/

				if ( ClErr ) {
					delete *iter;
					iter = Server->m_Clients.erase( iter );
				}

Ich möchte alle Elemente durchgehen, allerdings kann es vorkommen,
dass ich beim iterieren std::vector::erase aufrufe und somit der Iterator
ungültig wird.

C++:
				if ( ClErr ) {
					delete *iter;
					iter = Server->m_Clients.erase( iter );
				}

Gibt es da eine Möglichkeit den Iterator auf das nächte
Element nach dem gelöschtem zeigen zu lassen?
 
Zuletzt bearbeitet von einem Moderator:
Leider nicht, getestet habe ich dies mit einem Element im vector.

std::vector::erase sollte std::vector::end zurückliefern falls man die letzte
Position herausnimmt, andernfalls den iterator auf das Element nach dem
gelöschtem. Scheint nicht der Fall zu sein, da auf die Schleife weiterhin eingegangen wird und ich eine außnahme bekomme welche mir sagt: "map/set iterator not incrementable".

EDIT:
So wie es aussieht habe ich mich total verfrantzt...
Es geht eher gesagt um eine map, aus der ich jetzt allerdings einen vector gemacht habe, allerdings wieder genau
das was auch bei der map eingetreten ist. Ich habe genau ein Element im vector und dieses wird erase entfernt nun sollte
erase std:vector::end zurück gegeben werden und die bedingung für die schleife nicht mehr erfüllt sein, allerdings wird der
preincrement operator trotzdem aufgerufen. Den quelltext habe ich im ersten post geändert.
 
Zuletzt bearbeitet:
Hm bei deinem Code oben ... Magic Numbers rauswerfen, eh insert auf end-Iterator!? Sicher das du das willst?! :D rbegin() wäre wohl eher passend ;)

Dann solltest du dir mal angucken wann in C++ welcher Teil einer for-Schleife ausgeführt wird :D Tipp... du zeigst eins hinter ende :P
 
Stimmt auf end() iterator insert() kommt nicht so gut, mit dem
reverse_iterator von rbegin() allerdings auch nich. Dann halt begin() +.

Stimmt mit der for schleife hab ich ein klein wenig gepennt ;)

Gut, läuft nun alles soweit, danke für die Hilfe.
 
Zurück