Andre said:
Or... it probably starting copying from j+1 onto i (and j+2 to i+1, etc)
until (again) it eventually walked off the end of the vector. Then by
happenstance it stopped before actually crashing your problem (or perhaps
a debug-mode version of the standard library that checked to make sure
that you don't iterate off the end of a container). In either case, it's
still Undefined Behaviour.
Implementation of erase(iterator::start, itertaor::end) first does a
copy from [iterator::end, vector::end()] in to vector starting at
iterator::start. So when iterator::end > iterator::start world is fine.
But when iterator::start > iterator::end then it would actuall copy
from iterator::start (which is greater than iterator::end till
vector::end() ) to vector::end() starting from iterator::end. Hence
instead of deleting it adds to the end first and then deletes from the
difference.
Below is one the implementation of vector::erase() which I thought
might be usefull in understanding the behaviour.
iterator __i(std::copy(__last, end(), __first));
std::_Destroy(__i, end());
this->_M_impl._M_finish = this->_M_impl._M_finish - \
(__last - __first);
return __first;
I am not sure as to why it was done this way but I think it's
developers responsibility to ensure that iterator::end >
iterator::start.
I did try out the example posted.
$ cat vec.cpp
#include <vector>
#include <iostream>
int main(int argc, char** argv) {
std::vector<int> x(10);
std::vector<int>::iterator i=x.begin()+2, j=x.begin()+6;
std::cout << "Size of vector " << x.size() << std::endl;
x.erase(i,j);
std::cout << "Size of vector " << x.size() << std::endl;
x.erase(j,i);
std::cout << "Size of vector " << x.size() << std::endl;
return 0;
}
$ ./a.out
Size of vector 10 [ Before deletion ]
Size of vector 6 [ After deletion ]
Size of vector 10 [ Adds 8 and then deletes 4 ]
$
Thank you,
Nitin Motgi (nmotgi)