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
}
}
}
}