vector.erase(iterator iter) will change "iter" or not?

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • thomas

    #1

    vector.erase(iterator iter) will change "iter" or not?

    suppose I will delete an element pointed to by "iter".
    like this:

    vector<ints;
    for(vector<int> ::iterator iter=s.begin(); iter!=s.end(); iter++){
    if(*iter==3)
    s.erase(iter); //A
    }

    in line A, if element by "iter" is erased, will "iter" point to the
    next element(now should be the current element) automatically?
  • Victor Bazarov

    #2
    Re: vector.erase(it erator iter) will change &quot;iter&quot ; or not?

    thomas wrote:
    suppose I will delete an element pointed to by "iter".
    like this:
    >
    vector<ints;
    for(vector<int> ::iterator iter=s.begin(); iter!=s.end(); iter++){
    if(*iter==3)
    s.erase(iter); //A
    }
    >
    in line A, if element by "iter" is erased, will "iter" point to the
    next element(now should be the current element) automatically?
    The iterator that refers to the removed element and all elements
    after the removed one are invalidated by that operation. IOW, the
    Standard makes no attempt to define what the 'iter' would point to
    after being erased.

    V
    --
    Please remove capital 'A's when replying by e-mail
    I do not respond to top-posted replies, please don't ask


    Comment

    • =?utf-8?Q?David_C=C3=B4me?=

      #3
      Re: vector.erase(it erator iter) will change &quot;iter&quot ; or not?

      On Thu, 21 Feb 2008 15:16:11 +0100, thomas <FreshThomas@gm ail.comwrote:
      suppose I will delete an element pointed to by "iter".
      like this:
      >
      vector<ints;
      for(vector<int> ::iterator iter=s.begin(); iter!=s.end(); iter++){
      if(*iter==3)
      s.erase(iter); //A
      }
      >
      in line A, if element by "iter" is erased, will "iter" point to the
      next element(now should be the current element) automatically?
      Do :

      vector<ints;
      for(vector<int> ::iterator iter=s.begin(); iter!=s.end(); iter++){
      if(*iter==3)
      iter= s.erase(iter);
      }

      Comment

      • thomas

        #4
        Re: vector.erase(it erator iter) will change &quot;iter&quot ; or not?

        (And the higher-level answer to his question is that he should probably
        be using std::remove anyway:
        >
        s.erase(remove( s.begin(), s.end(), 3), s.end());
        >
        What's this?
        will "s.erase()" get all the elements after "3" removed?

        Comment

        • Eric Pruneau

          #5
          Re: vector.erase(it erator iter) will change &quot;iter&quot ; or not?


          "thomas" <FreshThomas@gm ail.coma écrit dans le message de news:
          c69c72bd-a326-4bc5-b1ef-4dd03288d4f4...l egroups.com...
          >
          >(And the higher-level answer to his question is that he should probably
          >be using std::remove anyway:
          >>
          >s.erase(remove (s.begin(), s.end(), 3), s.end());
          >>
          >
          What's this?
          will "s.erase()" get all the elements after "3" removed?
          remove will remove all element equal to 3. beware, removing is not
          erasing... Remove returns an iterator to the new end of the sequence s (it
          does not actually modify s.end() ) , so you can use this iterator in the
          vector::erase function. The size of the vector is not modified after a
          remove, but the element between the returned end and the actual s.end() but
          the element are unspecified.

          so you can do

          vector<int>::it erator NewEnd = remove(s.begin( ), s.end(), 3);
          s.erase(NewEnd, s.end);


          Eric Pruneau


          Comment

          • Martin York

            #6
            Re: vector.erase(it erator iter) will change &quot;iter&quot ; or not?


            Just a small correction.
            vector<ints;
            for(vector<int> ::iterator iter=s.begin(); iter!=s.end(); iter++){
            if(*iter==3)
            iter= s.erase(iter);
            }
            After the erase() call iter points at the next element in the
            container. Thus when the iter++ is called you will effectively skip
            an element or if the erased element is the last element it now points
            one after end().

            Also for efficiency it is a god idea to get in the habit of using
            prefix increment (In this case it probably makes no difference but
            for the generic case it does).

            Comment

            • Old Wolf

              #7
              Re: vector.erase(it erator iter) will change &quot;iter&quot ; or not?

              On Feb 22, 11:54 pm, Richard Herring <junk@[127.0.0.1]wrote:
              If it doesn't point anywhere, it points nowhere. "nowhere" looks pretty
              invalid to me.
              Non-sequitur ; there are three possible states for
              pointers (or iterators): pointing to a valid object,
              null, or indeterminate. By 'anywhere' I do not
              include the indeterminate case.

              Comment

              • Old Wolf

                #8
                Re: vector.erase(it erator iter) will change &quot;iter&quot ; or not?

                On Feb 22, 8:47 pm, Triple-DES <fire13...@hotm ail.comwrote:
                That's an interesting point. Consider:
                int * p = new int(441);
                delete p;
                >
                Would you say that the last line changes the value of p?
                Yes

                Comment

                • Richard Herring

                  #9
                  Re: vector.erase(it erator iter) will change &quot;iter&quot ; or not?

                  In message
                  <ee7bf0ee-1e6d-4b5c-9e66-8d72052145b7@64 g2000hsw.google groups.com>, Old
                  Wolf <oldwolf@inspir e.net.nzwrites
                  >On Feb 22, 11:54 pm, Richard Herring <junk@[127.0.0.1]wrote:
                  [big snip noted]
                  >If it doesn't point anywhere, it points nowhere. "nowhere" looks pretty
                  >invalid to me.
                  >
                  >Non-sequitur ; there are three possible states for
                  >pointers (or iterators): pointing to a valid object,
                  >null, or indeterminate.
                  The standard refers to this state as "[having] singular values".
                  >By 'anywhere' I do not
                  >include the indeterminate case.
                  But you obviously meant "not anywhere" to include singular states when
                  you wrote this:
                  >>previously it was well-defined and now it is indeterminate! It
                  >>>doesn't point anywhere;
                  --
                  Richard Herring

                  Comment

                  • Old Wolf

                    #10
                    Re: vector.erase(it erator iter) will change &quot;iter&quot ; or not?

                    On Feb 23, 2:38 am, Richard Herring <junk@[127.0.0.1]wrote:
                    But you obviously meant "not anywhere" to include singular states when
                    you wrote this:
                    >
                    >previously it was well-defined and now it is indeterminate! It
                    >>doesn't point anywhere;
                    Actually I didn't. I'll try to use more precise
                    terms than "anywhere" in future.

                    Comment

                    • James Kanze

                      #11
                      Re: vector.erase(it erator iter) will change &quot;iter&quot ; or not?

                      On Feb 21, 6:45 pm, Martin York <Martin.YorkAma ...@gmail.comwr ote:

                      [...]
                      Also for efficiency it is a god idea to get in the habit of
                      using prefix increment (In this case it probably makes no
                      difference but for the generic case it does).
                      Measurements? Or is this just speculation on your part. (I've
                      actually measured with g++, and all of the standard iterators.
                      No measurable difference.)

                      --
                      James Kanze (GABI Software) email:james.kan ze@gmail.com
                      Conseils en informatique orientée objet/
                      Beratung in objektorientier ter Datenverarbeitu ng
                      9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

                      Comment

                      • Old Wolf

                        #12
                        Re: vector.erase(it erator iter) will change &quot;iter&quot ; or not?

                        On Feb 23, 6:40 am, James Kanze <james.ka...@gm ail.comwrote:
                        unsigned char before[ sizeof( std::vector<int >::iterator ] ;
                        memcpy( before, &iter, sizeof( std::vector<int >::iterator ) ) ;
                        v.erase( iter ) ;
                        memcmp( before, &iter, sizeof( std::vector<int >::iterator ) ) ;
                        >
                        the memcmp will return a value not equal to 0.
                        How does that work? I agree that it's legal, but I wouldn't
                        expect it anywhere except the DS9000; it seems that the
                        implementation, when faced with vector::erase, would have
                        to go out of its way to go and change bits in the original
                        'iter' that the parameter to vector::erase was copied from.
                        And trying to use the iterator will cause a core dump.
                        To be expected when using indeterminate 'values'.

                        Comment

                        • Richard Herring

                          #13
                          Re: vector.erase(it erator iter) will change &quot;iter&quot ; or not?

                          In message
                          <a2f9ee21-5d0c-4728-b8ce-0837e6a15c0e@f4 7g2000hsd.googl egroups.com>,
                          James Kanze <james.kanze@gm ail.comwrites
                          >Old Wolf wrote:
                          >On Feb 23, 6:40 am, James Kanze <james.ka...@gm ail.comwrote:
                          unsigned char before[ sizeof( std::vector<int >::iterator ] ;
                          memcpy( before, &iter, sizeof( std::vector<int >::iterator ) ) ;
                          v.erase( iter ) ;
                          memcmp( before, &iter, sizeof( std::vector<int >::iterator ) ) ;
                          >
                          the memcmp will return a value not equal to 0.
                          >
                          >How does that work?
                          >
                          >About how you'd expect. The container knows about the iterators
                          >which refer to it, and marks them as invalid whenever it
                          >invalidates them.
                          >
                          >I agree that it's legal, but I wouldn't expect it anywhere
                          >except the DS9000; it seems that the implementation, when
                          >faced with vector::erase, would have to go out of its way to
                          >go and change bits in the original 'iter' that the parameter
                          >to vector::erase was copied from.
                          >
                          >I'm not sure what you mean by "go out of its way".
                          Iterate through every copy of every iterator ever generated from that
                          container, to see if it references the region that's about to be
                          invalidated?
                          Every
                          >pre-standard iterator I ever wrote did this. Logically, the
                          >iterator knows about the container, and vice versa.
                          But physically it need not: see implementations where
                          vector<T>::iter ator is implemented as plain T*.

                          --
                          Richard Herring

                          Comment

                          • James Kanze

                            #14
                            Re: vector.erase(it erator iter) will change &quot;iter&quot ; or not?

                            On Feb 26, 11:31 am, Richard Herring <junk@[127.0.0.1]wrote:
                            In message
                            <79bc8204-9fcd-4cae-808b-d6b179de1...@v3 g2000hsc.google groups.com>,
                            James Kanze <james.ka...@gm ail.comwrites
                            But physically it need not: see implementations where
                            vector<T>::iter ator is implemented as plain T*.
                            It's not *required* by the STL. All of the good implementations
                            do it.
                            No doubt, if you define "good" implementations as the ones
                            that do it.
                            I define good by those which are standards conformant, and work
                            as advertised. Basically, Dinkumware and g++.
                            It's a shame they can't do the same for all the references and
                            pointers that also become invalidated.
                            That is, of course, a language issue, rather than a library
                            issue. The Boehm collector goes a long way in this regard, but
                            obviously, it can't help in cases where the memory is managed
                            elsewhere (e.g. in std::vector, but also things like pointers to
                            local variables).

                            --
                            James Kanze (GABI Software) email:james.kan ze@gmail.com
                            Conseils en informatique orientée objet/
                            Beratung in objektorientier ter Datenverarbeitu ng
                            9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

                            Comment

                            Working...