Jump to content
  • Advertisement
Sign in to follow this  
Robert007

Erase elements from std::vector for socket programming

This topic is 3065 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi, Folks, There is a bug in the following loop for socket programming:
void f(std::vector<int>& socketlist) {
  std::vector::iterator itr;
  for (itr = socketlist.begin(); itr != socketlist.end(); ++itr) { // loop
     if ( 10 == *itr ) {     // simplified for some condition of the socket
         socketlist.erase( itr );
         itr--;              // bug
     }                       // the loop should continue with itr
}


Since it is used for a server program, it would be an expensive operation for working around it with a copy of socketlist. In addition, the code should work for the following cases: (1) Input vector: 10, 20, 50, 70 // remove head element 10 Output: 20, 50, 70 with itr points to 20 to loop on with the for statement (2) Input vector: 10, 20, 50, 70 // remove middle element 20 Output: 10, 50, 70 with itr points to 50 to loop on with the for statement (3) Input vector: 10, 20, 50, 70 // remove last element 70 Output: 10, 20, 50 with itr points to 50 to loop on with the for statement (4) Input vector: 10 // remove the single element 10 Output: empty vector with itr points to vec.end() to loop on with the for statement I came up with a fix that works for multiple elements cases (1), (2), (3), but not for (4), because vec::clear() invalidates all iterator (i.e., itr can not be used for looping on with the for statement). Any idea on how to do it? Thank you ! P.S. vector is the least structure for this kind of removing operation. Since it is already being used in production code, I have to stick with std::vector.
void erase(std::vector<int>& socketlist) {
   std::vector<int>::iterator itr, list_end, cur;
   for (itr = socketlist.begin(); itr != socketlist.end(); ++itr) {
         if ( 10 == *itr ) {
	    if ( socketlist.size() != 1 ) {
	       if( (itr + 1 )== socketlist.end() ) {// itr ppoints to last element
		   cur = itr -1;
	       } else {	            // other cases
		   cur = itr;
	       }			
	       list_end = std::remove(socketlist.begin(), 
                        socketlist.end(), 
                        *itr );	// now last vector item duplicated !
	       socketlist.erase(list_end, socketlist.end() );	// compact
	       itr = cur;
	    } else {            // remove a single element from the vector
	      socketlist.clear( );
	      itr = socketlist.end();			// does not work
	    }
	}			
    }		
}







Share this post


Link to post
Share on other sites
Advertisement
The canonical loop for erasing from a vector while iterating over it looks like:

for (iterator itr = vec.begin(); itr != vec.end();) {
if (condition) {
itr = vec.erase(itr);
} else {
++itr;
}
}

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!