Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   C++ (http://www.velocityreviews.com/forums/f39-c.html)
-   -   Deleting from std::list (http://www.velocityreviews.com/forums/t276972-deleting-from-std-list.html)

Martin Magnusson 08-21-2003 11:33 PM

Deleting from std::list
 
I know a similar question was recently posted here, but after trying the
solutions in that thread I still have problems.

list<int> the_list;
the_list.push_back(1);
the_list.push_back(2);
the_list.push_back(3);
the_list.push_back(4);
list<int>::iterator i = the_list.end();
i--;
cout << the_list.size();
for (std::list<int>::iterator j = i;
j != the_list.end();
++j)
{
cout << ".";
j = the_list.erase( j );
}
cout << the_list.size();

What happens is this: j goes to the end of the list and erases the last
element. By then I would have thought that j would be set to nodes.end()
and the loop would terminate, but instead it seems that the loop keeps
running, erasing all of the list. The output of the above code is
"4....0". What am I doing wrong?


Victor Bazarov 08-22-2003 12:05 AM

Re: Deleting from std::list
 
"Martin Magnusson" <loveslave@frustratedhousewives.zzn.com> wrote...
> I know a similar question was recently posted here, but after trying the
> solutions in that thread I still have problems.
>
> list<int> the_list;
> the_list.push_back(1);
> the_list.push_back(2);
> the_list.push_back(3);
> the_list.push_back(4);
> list<int>::iterator i = the_list.end();
> i--;
> cout << the_list.size();
> for (std::list<int>::iterator j = i;
> j != the_list.end();
> ++j)


What's the purpose of ++j here?

> {
> cout << ".";
> j = the_list.erase( j );
> }
> cout << the_list.size();
>
> What happens is this: j goes to the end of the list and erases the last
> element. By then I would have thought that j would be set to nodes.end()
> and the loop would terminate, but instead it seems that the loop keeps
> running, erasing all of the list. The output of the above code is
> "4....0". What am I doing wrong?


Why are you increasing 'j'? Once 'j' is set to the_list.end(),
using ++ for it causes undefined behaviour. If an iterator is
"one past the end", it is not dereferenceable, which is a pre-
condition for ++.

Victor



Mike Wahler 08-22-2003 12:25 AM

Re: Deleting from std::list
 
Martin Magnusson <loveslave@frustratedhousewives.zzn.com> wrote in message
news:bi3l02$fe7$1@green.tninet.se...
> I know a similar question was recently posted here, but after trying the
> solutions in that thread I still have problems.
>
> list<int> the_list;
> the_list.push_back(1);
> the_list.push_back(2);
> the_list.push_back(3);
> the_list.push_back(4);
> list<int>::iterator i = the_list.end();
> i--;
> cout << the_list.size();
> for (std::list<int>::iterator j = i;


So now 'j' points to the last element (with value of 4.)

> j != the_list.end();
> ++j)
> {
> cout << ".";
> j = the_list.erase( j );


Now 'j' == the_list.end()
We go back to the top of the loop, where 'j' is incremented.
(past end()). Heaven knows what the 'value' of 'j' is now,
but it's not equal to 'end()'. So the body of the loop
executes again. :-)

I think we have undefined behavior here.


> }
> cout << the_list.size();
>
> What happens is this: j goes to the end of the list and erases the last
> element. By then I would have thought that j would be set to nodes.end()
> and the loop would terminate, but instead it seems that the loop keeps
> running, erasing all of the list. The output of the above code is
> "4....0". What am I doing wrong?



Try:

for (std::list<int>::iterator j = i;
j != the_list.end();
j = the_list.erase(j))
{
cout << ".";
}

or

for (std::list<int>::iterator j = i;
j != the_list.end();
/* no iteration expression */ )
{
cout << ".";
j = the_list.erase(j);
}

Your '++j' was overwriting the return from erase that
you stored in 'j'.

I must admit it did take me a few minutes to realize
what was going on. :-)

HTH,
-Mike




John Harrison 08-22-2003 10:42 AM

Re: Deleting from std::list
 

"Martin Magnusson" <loveslave@frustratedhousewives.zzn.com> wrote in message
news:bi3l02$fe7$1@green.tninet.se...
> I know a similar question was recently posted here, but after trying the
> solutions in that thread I still have problems.
>
> list<int> the_list;
> the_list.push_back(1);
> the_list.push_back(2);
> the_list.push_back(3);
> the_list.push_back(4);
> list<int>::iterator i = the_list.end();
> i--;
> cout << the_list.size();
> for (std::list<int>::iterator j = i;
> j != the_list.end();
> ++j)
> {
> cout << ".";
> j = the_list.erase( j );
> }
> cout << the_list.size();
>
> What happens is this: j goes to the end of the list and erases the last
> element. By then I would have thought that j would be set to nodes.end()
> and the loop would terminate, but instead it seems that the loop keeps
> running, erasing all of the list. The output of the above code is
> "4....0". What am I doing wrong?
>


But that isn't the solution that was posted recently. If you really tried
the solution posted recently you would have more luck.

Your problem is that j is set to nodes.end(), but what is the next thing you
do? ++j of course!

This is the correct solution.

for (std::list<int>::iterator j = i;
j != the_list.end();
)
{
cout << ".";
j = the_list.erase( j );
}

Note that ++j has disappeared.

john



Martin Magnusson 08-22-2003 02:32 PM

Re: Deleting from std::list
 
Thanks for your answers, all of you! I wasn't aware that the ++j was
executed before the comparison j!=the_list.end().



Stuart Golodetz 08-22-2003 03:13 PM

Re: Deleting from std::list
 
"Martin Magnusson" <loveslave@frustratedhousewives.zzn.com> wrote in message
news:bi59l9$jac$1@green.tninet.se...
> Thanks for your answers, all of you! I wasn't aware that the ++j was
> executed before the comparison j!=the_list.end().


A couple more things:

1)

If you really just want to remove the last element of a list, you're better
off just writing:

the_list.pop_back();

2)

Regarding for loops, if you have something like this:

for(int i=0; i<3; ++i)
{
std::cout << i << ' ';
}

What actually happens is something like this (using an "infinite" while
loop, to make things clear):

int i = 0;
while(1)
{
if(!(i < 3)) break;
std::cout << i << ' ';
++i;
}

Hope that clarifies things a bit?

Cheers,

Stuart.




All times are GMT. The time now is 12:53 AM.

Powered by vBulletin®. Copyright ©2000 - 2014, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.