Re: STL Vector: Unexpected behavior



bob wrote:
> for (localIterator = localVector.begin(); localIterator !=
> localVector.end(); ++localIterator) {
> MyClass* obj_ptr = *localIterator; // dereference to get element
> if(obj_ptr->some_field == true) do_stuff();
> else do_different_stuff();
> // now remove element from list
> localVector.erase(remove(localVector.begin(), localVector.end(),
> *localIterator), localVector.end());
> } // end of for loop

Erasing an element from a container always invalidates the iterator used for
the deletion, i.e. you can't use it afterwards, not even increment it to
the next element. For a vector, you should expect it to invalidate every
iterator of that container. Also, removing elements from the middle of a
vector is a slow operation, you should use list<> instead, then you can use
this simple algorithm:

iterator it = the_list.begin();
while(it!=the_list.end)
{
if(some_condition(*it))
the_list.erase(it++);
else
++it;
}

Other than that, you could move all pointers you want to keep to a new
vector and then swap the former one with it.

> This results in an error since there is nothing
> in the vector to dereference!

Yes, you also omit checking if the pointer is zero in your loop. I'd
consider using boost::shared_ptr<>, btw.

> for (unsigned index = 0; index < localVector.size; ++index)
>
> Whilst that _may_ solve the problem, it won't allow me to _understand_
> why the other approach doesn't work.

No, this also doesn't work, because when you erase an element from the
middle and then increment 'index' you skipped an element.

Uli

.



Relevant Pages

  • Re: Ada Popularity: Comparison of Ada/Charles with C++ STL (and Perl)
    ... > while Has_Element loop ... > container, the passive iterator is preferred: ... > If you have an array type, then you can give it a container-like ...
    (comp.lang.ada)
  • Re: help a newbie with vectors
    ... I usually prefer the approach of earlier posters: ... There is nothing wrong with the above loop, but it really is a "for" ... since you are not using the iterator to ... modify the container, make it a const_iterator: ...
    (comp.lang.cpp)
  • Re: Pointer To A Vector Elements While Still Adding
    ... : The following would compile (for iterators that are not built-in types): ... > that with the pointers, ... the iterator is the obvious choice. ... - avoids exposing they type of container used for the storage ...
    (comp.lang.cpp)
  • Re: vector question
    ... If I undesrstand correctly, vector is not an "associative" container, so you ... A simple loop using an iterator (or ... so I'm guessing you've got some way to identify the ...
    (comp.lang.cpp)
  • Problem: Trying to merge two Ranges into a Hash
    ... I'm trying to take two ranges ... easily do this with a loop but I want to use an iterator and I'm not ... the community - thanks for any pointers:) ...
    (comp.lang.ruby)