Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > vector.erase(iterator iter) will change "iter" or not?

Reply
Thread Tools

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

 
 
Richard Herring
Guest
Posts: n/a
 
      02-22-2008
In message
<(E-Mail Removed)>, Old
Wolf <(E-Mail Removed)> writes
>On Feb 22, 4:31 am, Richard Herring <junk@[127.0.0.1]> wrote:
>> In message <fpk2sg$(E-Mail Removed)>, Victor Bazarov
>> >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.

>>
>> I wonder if the OP is confused because the iterator is passed by value
>> and therefore not modified? Obviously erase(iter) can't change its
>> _value_, but it certainly changes its _meaning_ - what it points to is
>> no longer valid.

>
>The value certainly is changed: previously it was
>well-defined and now it is indeterminate!


Its value has become singular, certainly, but that's because the set of
singular values has changed, not because the iterator has.

> It doesn't
>point anywhere; it's nonsensical to say that what
>it points to is not valid.


If it doesn't point anywhere, it points nowhere. "nowhere" looks pretty
invalid to me.

> Perhaps you mean to say
>that the representation isn't changed;


Perhaps.

--
Richard Herring
 
Reply With Quote
 
 
 
 
Old Wolf
Guest
Posts: n/a
 
      02-22-2008
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.
 
Reply With Quote
 
 
 
 
Old Wolf
Guest
Posts: n/a
 
      02-22-2008
On Feb 22, 8:47 pm, Triple-DES <(E-Mail Removed)> wrote:
> 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
 
Reply With Quote
 
Richard Herring
Guest
Posts: n/a
 
      02-22-2008
In message
<(E-Mail Removed)>, Old
Wolf <(E-Mail Removed)> writes
>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
 
Reply With Quote
 
Old Wolf
Guest
Posts: n/a
 
      02-22-2008
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.
 
Reply With Quote
 
James Kanze
Guest
Posts: n/a
 
      02-22-2008
On Feb 22, 8:31 am, Old Wolf <(E-Mail Removed)> wrote:
> On Feb 22, 4:31 am, Richard Herring <junk@[127.0.0.1]> wrote:


> > In message <fpk2sg$(E-Mail Removed)>, Victor Bazarov
> > >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.


> > I wonder if the OP is confused because the iterator is
> > passed by value and therefore not modified? Obviously
> > erase(iter) can't change its _value_, but it certainly
> > changes its _meaning_ - what it points to is no longer
> > valid.


> The value certainly is changed: previously it was
> well-defined and now it is indeterminate!


I'm not sure whether you can use the word "changed" here or
not. After the erase, iter has no value. At least, not one you
can legally access.

> It doesn't point anywhere; it's nonsensical to say that what
> it points to is not valid. Perhaps you mean to say that the
> representation isn't changed;


Not with the implementation I use After the erase, the only way
you could look at the representation is by means of a memcpy,
and if you do:

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.

And trying to use the iterator will cause a core dump. (To be
very, very clear:

#include <vector>

int
main()
{
static int const init[] = { 1, 2, 3, 4, 5 } ;
std::vector< int > v( init, init + 5 ) ;
std::vector< int >::iterator
iter = v.begin() + 3 ;
v.erase( iter ) ;
std::vector< int >::iterator
i2 = iter ;
}

core dumps on the last line in main. You cannot read an invalid
iterator other than as an array of bytes.)

--
James Kanze (GABI Software) email:(E-Mail Removed)
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
 
Reply With Quote
 
James Kanze
Guest
Posts: n/a
 
      02-22-2008
On Feb 22, 11:54 am, Richard Herring <junk@[127.0.0.1]> wrote:
> In message
> <(E-Mail Removed)>, Old
> Wolf <(E-Mail Removed)> writes


> >On Feb 22, 4:31 am, Richard Herring <junk@[127.0.0.1]> wrote:
> >> In message <fpk2sg$(E-Mail Removed)>, Victor Bazarov
> >> >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.


> >> I wonder if the OP is confused because the iterator is
> >> passed by value and therefore not modified? Obviously
> >> erase(iter) can't change its _value_, but it certainly
> >> changes its _meaning_ - what it points to is no longer
> >> valid.


> >The value certainly is changed: previously it was
> >well-defined and now it is indeterminate!


> Its value has become singular, certainly, but that's because
> the set of singular values has changed, not because the
> iterator has.


> >It doesn't point anywhere; it's nonsensical to say that what
> >it points to is not valid.


> If it doesn't point anywhere, it points nowhere. "nowhere"
> looks pretty invalid to me.


It doesn't point, period.

> > Perhaps you mean to say that the representation isn't
> > changed;


> Perhaps.


Consider:

#include <vector>
#include <cstring>
#include <iostream>

int
main()
{
static int const init[] = { 1, 2, 3, 4, 5 } ;
std::vector< int > v( init, init + 5 ) ;
std::vector< int >::iterator
iter = v.begin() + 3 ;
unsigned char before[ sizeof( iter ) ] ;
std::memcpy( before, &iter, sizeof( iter ) ) ;
v.erase( iter ) ;
if ( std::memcmp( before, &iter, sizeof( iter ) ) == 0 ) {
std::cout << "unchanged" << std::endl ;
} else {
std::cout << "changed" << std::endl ;
}
}

On my implementation, this outputs "changed". And any attempt
to access iter as an std::vector< int >::iterator (e.g. to copy
it, compare it, etc.) generates a core dump.

I don't quite know what you mean by "its representation". If
it's just the underlying bits in memory, then it's changed. If
it's anything else, then you can't tell, because there's nothing
you can do other than look at the bytes that has defined
behavior (and the implementation I normally use core dumps in
all of the cases of undefined behavior).

--
James Kanze (GABI Software) email:(E-Mail Removed)
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
 
Reply With Quote
 
James Kanze
Guest
Posts: n/a
 
      02-22-2008
On Feb 21, 6:45 pm, Martin York <(E-Mail Removed)> wrote:

[...]
> 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:(E-Mail Removed)
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

 
Reply With Quote
 
Old Wolf
Guest
Posts: n/a
 
      02-23-2008
On Feb 23, 6:40 am, James Kanze <(E-Mail Removed)> wrote:
> 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'.
 
Reply With Quote
 
James Kanze
Guest
Posts: n/a
 
      02-23-2008
Old Wolf wrote:
> On Feb 23, 6:40 am, James Kanze <(E-Mail Removed)> wrote:
> > 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". Every
pre-standard iterator I ever wrote did this. Logically, the
iterator knows about the container, and vice versa.

> > And trying to use the iterator will cause a core dump.


> To be expected when using indeterminate 'values'.


Huh? On my system, I don't get a core dump just because I copy
an invalid pointer (say, after a delete). I do if I copy an
invalid iterator, however. (If, after the erase above, I assign
iter to some other iterator, I get a core dump, with a message
that I've used an invalid iterator.)

--
James Kanze (GABI Software) email:(E-Mail Removed)
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
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Democrat's "change," not pocket change Cyberiade.it Anonymous Remailer Computer Support 0 03-14-2009 07:07 AM
"Change your language and you change your thoughts." Suganya C Programming 0 04-29-2008 01:35 PM
Change the master GridView after detail change? Q. John Chen ASP .Net 0 11-15-2006 05:31 PM
Change the master GridView after detail change? Q. John Chen ASP .Net 0 11-15-2006 05:30 PM
A Paradise DNS address change? What change? There was no change. Tony Neville NZ Computing 7 09-22-2006 01:02 PM



Advertisments