STL vector

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • imcram
    New Member
    • Mar 2007
    • 15

    STL vector

    I've been receiving a constant stream run time errors using vectors.
    So, can anyone tell me if the second method is safer?

    1. for(vector<type >::iterator it = test_vector.beg in(); it != test_vector.end (); it++)

    2. for(vector<type >::iterator it = test_vector.beg in(); it < test_vector.end (); it++)

    My feeling is that the second one is better. If so, why don't I see it too much in tutorials and stuff?
  • JosAH
    Recognized Expert MVP
    • Mar 2007
    • 11453

    #2
    Originally posted by imcram
    I've been receiving a constant stream run time errors using vectors.
    So, can anyone tell me if the second method is safer?

    1. for(vector<type >::iterator it = test_vector.beg in(); it != test_vector.end (); it++)

    2. for(vector<type >::iterator it = test_vector.beg in(); it < test_vector.end (); it++)

    My feeling is that the second one is better. If so, why don't I see it too much in tutorials and stuff?
    Note that only random access iterators (as supplied by the vector class)
    implement the operator< therefore it's much safer to use the operator==
    for your test because that one works for *any* iterator type.

    Are you sure you haven't used a const vector? You have to use a const iterator
    for those containers.

    kind regards,

    Jos

    Comment

    • imcram
      New Member
      • Mar 2007
      • 15

      #3
      Originally posted by JosAH
      Note that only random access iterators (as supplied by the vector class)
      implement the operator< therefore it's much safer to use the operator==
      for your test because that one works for *any* iterator type.

      Are you sure you haven't used a const vector? You have to use a const iterator
      for those containers.

      kind regards,

      Jos
      Ok. Here's the problem. I use an iterator, check the value, and the use
      Code:
      test_vector.erase(it);
      the problem here is, after this, sometimes

      Code:
      it != test_vector.end()
      does not return false even if the iterator is beyond end. I can't pinpoint where my problem is exactly. That is why I thought using < operator would be better in this case. Any thoughts?

      Comment

      • JosAH
        Recognized Expert MVP
        • Mar 2007
        • 11453

        #4
        If you erase an element from your vector you must not increment the iterator.
        I haven't seen your code so this is just a guess.

        kind regards,

        Jos

        Comment

        • Ganon11
          Recognized Expert Specialist
          • Oct 2006
          • 3651

          #5
          Shouldn't the STL container take care of that, though? Does the vector automatically force the iterator to point to the previous element? If not, isn't there a .remove() function in the iterator itself? If so, you may want to use that.

          Comment

          • Banfa
            Recognized Expert Expert
            • Feb 2006
            • 9067

            #6
            If you erase an iterator in a vector then the iterator and all iterators to later entries in the vector become invalid. Following an erase operation you should not use the iterator erased.

            However the erase method returns a valid iterator to the next entry in the vector so you should do something like

            Code:
            IF (I AM GOING TO ERASE THIS ITERATOR)
            {
                NEXT ITERATOR = ERASE(THIS ITERATOR)
            }
            ELSE
            {
                NEXT ITERATOR = THIS ITERATOR+1
            }
            Note this pseudo code is showing the logic, it is not meant to imply you need 2 iterator variables.

            Also note that when you erase an entry in a vector (via an iterator or otherwise) the vector case to copy all entries in the vector down 1 slot (because memory in a vector is held in 1 contiguous block) so looping down a vector erasing each entry in turn is a particularly inefficient way to empty a vector.

            Comment

            • JosAH
              Recognized Expert MVP
              • Mar 2007
              • 11453

              #7
              Originally posted by Banfa
              If you erase an iterator in a vector then the iterator and all iterators to later entries in the vector become invalid. Following an erase operation you should not use the iterator erased.
              That is not entirely true: a vector never shrinks itself automagically; erasing
              an element of a vector just leaves one more unused slot at the end. If your
              iterator runs 'upwards' and you don't increment your iterator after a erase and
              you dynamically check the v.end() value, all is safe. e.g. the following removes
              the odd elements from a vector<int>:
              Code:
              for (vector<int>::iterator i= v.begin(); i != v.end(); ) 
              	if (*i&1) 
              		v.erase(i);
              	else
              		i++;
              In this scenario no new iterator needs to be used. I agree that other iterators
              that point beyond this point of deletion and don't have any notion of the
              deletion should take great care.

              kind regards,

              Jos

              Comment

              • Banfa
                Recognized Expert Expert
                • Feb 2006
                • 9067

                #8
                Originally posted by JosAH
                That is not entirely true: a vector never shrinks itself automagically;
                I know that :D I didn't think I said it did, however if you thought I did then the clarification is useful.

                Comment

                • JosAH
                  Recognized Expert MVP
                  • Mar 2007
                  • 11453

                  #9
                  Originally posted by Banfa
                  I know that :D I didn't think I said it did, however if you thought I did then the clarification is useful.
                  I was just following up on your phrase:

                  "Following an erase operation you should not use the iterator erased."

                  ;-)

                  kind regards,

                  Jos

                  Comment

                  Working...