473,473 Members | 1,844 Online
Bytes | Software Development & Data Engineering Community
Create Post

Home Posts Topics Members FAQ

unexpected result using std::list

I'm sure there's a good explanation for this effect, but I get rather
a strange output from this little test:

#include <iostream>
#include <list>

int main()
{
std::list<int> int_list;

int_list.push_back(1);
int_list.push_back(2);
int_list.push_back(3);
int_list.push_back(4);

std::list<int>::reverse_iterator rev = int_list.rbegin();
while(rev != int_list.rend())
{
std::cout << *rev++ << std::endl;
int_list.pop_back(); // This line causes a problem.
}
return 0;
}

Output:
4
3
2
1
0
0

The inclusion of the int_list.pop_back() call seems to cause the two
additional iterations through the loop that print the two extra zeros.
If I comment out the int_list.pop_back() line the output is as
expected, and if i use a different conditional statement such as
while(! int_list.empty()) the output is also as expected.

Does anyone know why this doesn't work? Are there member functions of
std::list that shouldn't be used with iterators, reverse-iterators or
something?

I'm using Red Hat 7 & g++.
Jul 19 '05 #1
3 3936
On 14 Oct 2003 07:20:15 -0700, mh*********@vodafone.net (Mike
Pemberton) wrote:
I'm sure there's a good explanation for this effect, but I get rather
a strange output from this little test:

#include <iostream>
#include <list>

int main()
{
std::list<int> int_list;

int_list.push_back(1);
int_list.push_back(2);
int_list.push_back(3);
int_list.push_back(4);

std::list<int>::reverse_iterator rev = int_list.rbegin();
while(rev != int_list.rend())
{
std::cout << *rev++ << std::endl;
int_list.pop_back(); // This line causes a problem.
The above line erases the element that rev is pointing to! Remember
that a reverse iterator's base iterator is actually the iterator to
the element after the one that dereferences. In any case, the above
line invalidates rev, so you can't legally perform any operations on
it, including comparing it to rend, dereferencing it and incrementing
it.
}
return 0;
}

Output:
4
3
2
1
0
0

The inclusion of the int_list.pop_back() call seems to cause the two
additional iterations through the loop that print the two extra zeros.
If I comment out the int_list.pop_back() line the output is as
expected, and if i use a different conditional statement such as
while(! int_list.empty()) the output is also as expected.

Does anyone know why this doesn't work? Are there member functions of
std::list that shouldn't be used with iterators, reverse-iterators or
something?


Yes, any list operation that erases an element invalidates all
iterators to that element. A reverse iterator is a strange beast,
since its base iterator is actually the one after the element it
dereferences to.

Tom
Jul 19 '05 #2
"Mike Pemberton" <mh*********@vodafone.net> wrote...
I'm sure there's a good explanation for this effect, but I get rather
a strange output from this little test:

#include <iostream>
#include <list>

int main()
{
std::list<int> int_list;

int_list.push_back(1);
int_list.push_back(2);
int_list.push_back(3);
int_list.push_back(4);

std::list<int>::reverse_iterator rev = int_list.rbegin();
while(rev != int_list.rend())
{
std::cout << *rev++ << std::endl;
int_list.pop_back(); // This line causes a problem.
}
return 0;
}

Output:
4
3
2
1
0
0

The inclusion of the int_list.pop_back() call seems to cause the two
additional iterations through the loop that print the two extra zeros.
If I comment out the int_list.pop_back() line the output is as
expected, and if i use a different conditional statement such as
while(! int_list.empty()) the output is also as expected.

Does anyone know why this doesn't work? Are there member functions of
std::list that shouldn't be used with iterators, reverse-iterators or
something?


Not sure off the top of my head, but at the time when you pop_back
the "last" element (at the moment when the list becomes empty), the
'rev' iterator may actually become screwed up.

Although the 'pop_back' is said to invalidate only the iterators and
references to the erased elements, the problem is that when pop_back
empties the list, iterators that used to be the same as the ends of
the list may become not the same any more, I think that's what you
are experiencing here.

For more clarification ask about it in comp.std.c++. FWIW, it could
be a defect in the Standard (the fact that it doesn't specify what
happens to the iterator which _is_ supposedly pointing 'one past the
end'.

Try this:
------------------------------------------------------------------
#include <string>
#include <iostream>
#include <list>
using namespace std;

int main()
{
list<int> int_list;

list<int>::reverse_iterator rev = int_list.rbegin();

cout << "'rev' is " << (rev == int_list.rend() ? "" : "NOT ")
<< "the same as 'rend()'\n";

cout << "Pushing '1'...\n";

int_list.push_back(1);

cout << "Resetting 'rev'...\n";

rev = int_list.rbegin();

cout << "'rev' is " << (rev == int_list.rend() ? "" : "NOT ")
<< "the same as 'rend()'\n";

cout << "'rev' points to " << *rev++ << std::endl;

cout << "After ++ ";

cout << "'rev' is " << (rev == int_list.rend() ? "" : "NOT ")
<< "the same as 'rend()'\n";

cout << "Popping the back\n";
int_list.pop_back(); // This line causes a problem.

cout << "'rev' is " << (rev == int_list.rend() ? "" : "NOT ")
<< "the same as 'rend()'\n";

string s;
getline(cin, s);
}

------------------------------------------------------------------

Victor

Jul 19 '05 #3
mh*********@vodafone.net (Mike Pemberton) wrote in message news:<bc**************************@posting.google. com>...
I'm sure there's a good explanation for this effect, but I get rather
a strange output from this little test:

#include <iostream>
#include <list>

int main()
{
std::list<int> int_list;

int_list.push_back(1);
int_list.push_back(2);
int_list.push_back(3);
int_list.push_back(4);

std::list<int>::reverse_iterator rev = int_list.rbegin();
while(rev != int_list.rend())
{
std::cout << *rev++ << std::endl;
int_list.pop_back(); // This line causes a problem.
}
return 0;
}

Output:
4
3
2
1
0
0

The inclusion of the int_list.pop_back() call seems to cause the two
additional iterations through the loop that print the two extra zeros.
If I comment out the int_list.pop_back() line the output is as
expected, and if i use a different conditional statement such as
while(! int_list.empty()) the output is also as expected.

Does anyone know why this doesn't work? Are there member functions of
std::list that shouldn't be used with iterators, reverse-iterators or
something?

I'm using Red Hat 7 & g++.


pop_back invalidates the iterator. Generally, insertions and deletions
invalidate iterators. I think this is what happens.
Jul 19 '05 #4

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

8
by: JustSomeGuy | last post by:
I need to write an new class derived from the list class. This class stores data in the list to the disk if an object that is added to the list is over 1K in size. What methods of the std stl...
8
by: ma740988 | last post by:
Consider: # include <iostream> using std::cout; using std::cin; using std::endl; # include <list> using std::list;
6
by: PengYu.UT | last post by:
Hi, Suppose I have a list which contains pointers. I want the pointer got by dereferencing the iterator be a pointer pointing to a const object. But std::list<const T*>::const_iterator doens't...
15
by: desktop | last post by:
If I have a sorted std::list with 1.000.000 elements it takes 1.000.000 operations to find element with value = 1.000.000 (need to iterator through the whole list). In comparison, if I have a...
8
by: Spoon | last post by:
Hello, Could someone explain why the following code is illegal? (I'm trying to use a list of (C-style) arrays.) #include <list> typedef std::list < int foo_t; int main() { int v = { 12, 34...
5
by: Christopher | last post by:
The situation is that a std::list<std::set<std::string is being iterated through. Upon certain criteria some sets become empty. I need to remove the empty sets from the list. Is it safe to...
0
by: Javier | last post by:
Hi all, I have this code: class A { std::list<Bm_observadores; void function() {
12
by: isliguezze | last post by:
template <class T> class List { public: List(); List(const List&); List(int, const T&); void push_back(const T &); void push_front(const T &); void pop_back();
17
by: Isliguezze | last post by:
Does anybody know how to make a wrapper for that iterator? Here's my wrapper class for std::list: template <class Tclass List { private: std::list<T*lst; public: List() { lst = new...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
1
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...
0
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and...
0
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
0
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.