By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
446,332 Members | 1,427 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 446,332 IT Pros & Developers. It's quick & easy.

Deleting from std::list

P: n/a
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?

Jul 19 '05 #1
Share this Question
Share on Google+
5 Replies


P: n/a
"Martin Magnusson" <lo*******@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
Jul 19 '05 #2

P: n/a
Martin Magnusson <lo*******@frustratedhousewives.zzn.com> wrote in message
news:bi**********@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

Jul 19 '05 #3

P: n/a

"Martin Magnusson" <lo*******@frustratedhousewives.zzn.com> wrote in message
news:bi**********@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
Jul 19 '05 #4

P: n/a
Thanks for your answers, all of you! I wasn't aware that the ++j was
executed before the comparison j!=the_list.end().
Jul 19 '05 #5

P: n/a
"Martin Magnusson" <lo*******@frustratedhousewives.zzn.com> wrote in message
news:bi**********@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.
Jul 19 '05 #6

This discussion thread is closed

Replies have been disabled for this discussion.