468,503 Members | 2,174 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 468,503 developers. It's quick & easy.

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?
Feb 21 '08 #1
13 7148
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
Feb 21 '08 #2
On Thu, 21 Feb 2008 15:16:11 +0100, thomas <Fr*********@gmail.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);
}
Feb 21 '08 #3
(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?
Feb 21 '08 #4

"thomas" <Fr*********@gmail.coma écrit dans le message de news:
c6**********************************...oglegroups.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>::iterator NewEnd = remove(s.begin(), s.end(), 3);
s.erase(NewEnd, s.end);
Eric Pruneau
Feb 21 '08 #5

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).

Feb 21 '08 #6
On Feb 22, 11:54 pm, Richard Herring <ju**@[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.
Feb 22 '08 #7
On Feb 22, 8:47 pm, Triple-DES <fire13...@hotmail.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
Feb 22 '08 #8
In message
<ee**********************************@64g2000hsw.g ooglegroups.com>, Old
Wolf <ol*****@inspire.net.nzwrites
>On Feb 22, 11:54 pm, Richard Herring <ju**@[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
Feb 22 '08 #9
On Feb 23, 2:38 am, Richard Herring <ju**@[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.
Feb 22 '08 #10
On Feb 21, 6:45 pm, Martin York <Martin.YorkAma...@gmail.comwrote:

[...]
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:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Feb 22 '08 #11
On Feb 23, 6:40 am, James Kanze <james.ka...@gmail.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'.
Feb 23 '08 #12
In message
<a2**********************************@f47g2000hsd. googlegroups.com>,
James Kanze <ja*********@gmail.comwrites
>Old Wolf wrote:
>On Feb 23, 6:40 am, James Kanze <james.ka...@gmail.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>::iterator is implemented as plain T*.

--
Richard Herring
Feb 25 '08 #13
On Feb 26, 11:31 am, Richard Herring <ju**@[127.0.0.1]wrote:
In message
<79bc8204-9fcd-4cae-808b-d6b179de1...@v3g2000hsc.googlegroups.com>,
James Kanze <james.ka...@gmail.comwrites
But physically it need not: see implementations where
vector<T>::iterator 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:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Feb 26 '08 #14

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

41 posts views Thread by AngleWyrm | last post: by
2 posts views Thread by Michael Olea | last post: by
4 posts views Thread by Generic Usenet Account | last post: by
4 posts views Thread by arnuld | last post: by
reply views Thread by NPC403 | last post: by
reply views Thread by fmendoza | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.