Problem with multiple iterators in a list.

Hi all,

I'm writing a program where I can place several Points on a map. The Points make up Loops. Theoretically, a line should be drawn between each Point in a Loop.

Right now, I'm try to cycle through all the Points in a Loop to do just this. The problem is figuring out what to do when my iterator has reached the end of the Loop and should draw a line back to the first Point in the Loop. (A Loop is basically a std::list<Point*>

Here's the offending code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
if(_pointList.size() > 1)
    {
        std::list<Point *>::iterator itr;
        std::list<Point *>::iterator itr2;

        for(itr = _pointList.begin(); itr != _pointList.end(); itr++)
        {
            if(itr != _pointList.end())
            {
                //set the second iterator to the next Point in the list.
                itr2 = itr;
                itr2++;
            }
            else
                itr2 = _pointList.begin();
                //this else statement is never reached. Why not?

            std::cout << "The first point's name is: " << (*itr)->name() << std::endl;
            std::cout << "The second point's name is: " << (*itr2)->name() << std::endl;

            //draw the line between the two points

        }
    }


I'm just not sure why that else statement is never reached. Obviously on the last pass through the for loop, itr == _pointList.end(). So why doesn't it work?

Any help would be much appreciated! Thank you!

Last edited on
Obviously on the last pass through the for loop, itr == _pointList.end().

No, that's not how for loops work. If the condition is not satisfied, the loop is not entered.
Right, whoops. So how can I make sure it goes through to the very end?

Also, if itr never gets to _pointList.end() then why would itr2 be segfaulting? Itr2 would never get past _pointList.end().
Last edited on
It does go through to the very end. _pointList.end() points one past the end.

The problem is that when processing the last element of the list, line 12 makes itr2 point one past the end and line 19 attempts to dereference that iterator.

Making it a list of points (why were they pointers anyway?) and using structs for simplicity,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <list>
#include <string>
#include <iostream>
struct Point {
    std::string name;
};
int main()
{
    std::list<Point> _pointList{{"foo"}, {"bar"}, {"baz"}};
    if(_pointList.size() > 1)
    {
        std::list<Point>::iterator itr;
        std::list<Point>::iterator itr2;

        for(itr = _pointList.begin(); itr != _pointList.end(); itr++)
        {
            //set the second iterator to the next Point in the list.
            itr2 = itr;
            itr2++;
            if(itr2 == _pointList.end())
               itr2 = _pointList.begin();

            std::cout << "The first point's name is: " << itr->name << '\n'
                      << "The second point's name is: " << itr2->name << '\n';
        }
    }
}

demo: http://ideone.com/9QYu2G
Wonderful answer. Thank you Cubbi. I guess I didn't understand exactly how _pointList.end() works. Now I know!

Not that it really matters, but since you asked, the Points are pointers because they are actually stored in a separate manager for manipulation, drawing, etc. and Loops just keep track of the specific Points that are related to it, merely for the purpose of drawing lines between them. Points are (usually) never accessed through their Loops and their memory is managed elsewhere, so I figured there's no reason for the actual Points themselves to reside in that list.

Also, I'm quite a newbie still and it may be that I shouldn't be using pointers, but since the Points (actually, smart pointers to them) are already contained in an std::map elsewhere, it seemed appropriate.
> but since the Points (actually, smart pointers to them) are already contained in an std::map
¿why that map, that has the ownership, has pointers instead of objects?
We're using smart pointers instead of objects in general basically to avoid having to keep track of data allocation (smart pointers do it for us). We're making a map editor that constantly has things being created and destroyed, so we wanted to make sure we didn't miss anything.
¿how will that be different with objects?
It would make sense if you've got several maps containing the points and sharing ownership
Well I don't have several MAPS, but I do have a map and a list sharing ownership...

If you're asking for a particularly good reason why I did it, I don't have one. I am still figuring this all out.

If you think what I did was idiotic, it probably is lol.
Topic archived. No new replies allowed.