List Iterator Not Incrementable?

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • freckred76@hotmail.com

    #1

    List Iterator Not Incrementable?

    Hi,

    I think this might be a VC++ problem. I am using Microsoft Visual
    Studio 2005 Full Version (8.0).

    I have a simple for loop that iterates over a list using the standard
    iterator. The list is populated with a struct _BLOCK defined as:

    typedef struct
    {
    int iX ;
    int iY ;
    int iFrame ;
    double dIntensity ;
    } _BLOCK ;

    std::list<_BLOC K> list_block;
    std::list<_BLOC K>::iterator list_block_it;

    for (list_block_it = list_block.begi n (); list_block_it !=
    list_block.end (); list_block_it++ )
    {
    list_block_it->dIntensity -= 0.025 ;
    if (list_block_it->dIntensity < 0.0)
    { // Delete this item
    list_block_it = list_block.eras e (list_block_it) ;
    }
    }

    The code seems fine to me, but it always fails an assert at run-time,
    claiming "list iterator not incrementable." I haven't been able to
    find any documentation or threads about this problem. Also, it seems
    like this code runs fine when built with g++ or previous versions of
    VC++.

    Any help is greatly appreciated,

    Nate

  • Ali Çehreli

    #2
    Re: List Iterator Not Incrementable?

    <freckred76@hot mail.com> wrote in message
    news:1137803247 .499825.272320@ o13g2000cwo.goo glegroups.com.. .
    [color=blue]
    > I have a simple for loop that iterates over a list using the standard
    > iterator. The list is populated with a struct _BLOCK defined as:
    >
    > typedef struct
    > {
    > int iX ;
    > int iY ;
    > int iFrame ;
    > double dIntensity ;
    > } _BLOCK ;
    >
    > std::list<_BLOC K> list_block;
    > std::list<_BLOC K>::iterator list_block_it;
    >
    > for (list_block_it = list_block.begi n (); list_block_it !=
    > list_block.end (); list_block_it++ )
    > {
    > list_block_it->dIntensity -= 0.025 ;
    > if (list_block_it->dIntensity < 0.0)
    > { // Delete this item
    > list_block_it = list_block.eras e (list_block_it) ;[/color]

    What if list_block_it becomes equal to list_block.end( ) at that point? It
    could happen if erase erases the last item in the list.

    Then, operator++ would be applied to an invalid iterator.
    [color=blue]
    > }
    > }
    >
    > The code seems fine to me, but it always fails an assert at run-time,
    > claiming "list iterator not incrementable."[/color]

    Your library is being very good to you :)
    [color=blue]
    > I haven't been able to
    > find any documentation or threads about this problem. Also, it seems
    > like this code runs fine when built with g++ or previous versions of
    > VC++.[/color]

    Since it's undefined behavior, you are being unlucky on those platforms
    because it "runs fine" on those platforms.

    Ali

    Comment

    • Andre Kostur

      #3
      Re: List Iterator Not Incrementable?

      freckred76@hotm ail.com wrote in news:1137803247 .499825.272320
      @o13g2000cwo.go oglegroups.com:
      [color=blue]
      > Hi,
      >
      > I think this might be a VC++ problem. I am using Microsoft Visual
      > Studio 2005 Full Version (8.0).
      >
      > I have a simple for loop that iterates over a list using the standard
      > iterator. The list is populated with a struct _BLOCK defined as:
      >
      > typedef struct
      > {
      > int iX ;
      > int iY ;
      > int iFrame ;
      > double dIntensity ;
      > } _BLOCK ;
      >
      > std::list<_BLOC K> list_block;
      > std::list<_BLOC K>::iterator list_block_it;
      >
      > for (list_block_it = list_block.begi n (); list_block_it !=
      > list_block.end (); list_block_it++ )
      > {
      > list_block_it->dIntensity -= 0.025 ;
      > if (list_block_it->dIntensity < 0.0)
      > { // Delete this item
      > list_block_it = list_block.eras e (list_block_it) ;[/color]

      And... kaboom (well, Undefined Behaviour). If you happen to be erasing
      the last element in your list, you'll increment it again for the for
      loop... thus you inadvertantly end up attemtping to iterate past the .end
      () iterator. BTW: it's possibly that you're compiling with a "debug-
      mode" standard library which is checking for things like attempting to
      increment past the end of a container.
      [color=blue]
      > }
      > }
      >
      > The code seems fine to me, but it always fails an assert at run-time,
      > claiming "list iterator not incrementable." I haven't been able to
      > find any documentation or threads about this problem. Also, it seems
      > like this code runs fine when built with g++ or previous versions of
      > VC++.[/color]

      Comment

      • freckred76@hotmail.com

        #4
        Re: List Iterator Not Incrementable?

        Ali,

        Yes, it may be undefined behavior, but it did work before, whereas now
        it does not. You were right about the source of the error. I modified
        the code to fix it. Thanks for your help! Sometimes you just don't
        notice the simple stuff.

        Nate

        Comment

        • red floyd

          #5
          Re: List Iterator Not Incrementable?

          freckred76@hotm ail.com wrote:[color=blue]
          > Hi,
          >
          > I think this might be a VC++ problem. I am using Microsoft Visual
          > Studio 2005 Full Version (8.0).
          >
          > I have a simple for loop that iterates over a list using the standard
          > iterator. The list is populated with a struct _BLOCK defined as:
          >
          > typedef struct
          > {
          > int iX ;
          > int iY ;
          > int iFrame ;
          > double dIntensity ;
          > } _BLOCK ;
          >
          > std::list<_BLOC K> list_block;
          > std::list<_BLOC K>::iterator list_block_it;
          >
          > for (list_block_it = list_block.begi n (); list_block_it !=
          > list_block.end (); list_block_it++ )
          > {
          > list_block_it->dIntensity -= 0.025 ;
          > if (list_block_it->dIntensity < 0.0)
          > { // Delete this item
          > list_block_it = list_block.eras e (list_block_it) ;
          > }
          > }[/color]

          Ali and Andre have already suggested the answer to your problem. I'd
          like to address something else.

          1. Your typedef is unnecessary, You should define it as "struct BLOCK"
          (note the lack of an underscore), which brigns me to...
          2. The identifier _BLOCK is reserved. Any identifier with a leading
          underscore followed by a capital letter is reserved to the implementation.

          Comment

          • freckred76@hotmail.com

            #6
            Re: List Iterator Not Incrementable?

            red floyd,

            I must admit that I did not write this code. I simply tried compiling
            it for a friend under 2003, which worked, and 2005, which did not work.
            I could not see a problem, when of course the problem was very
            obvious. However, let's not pick it to pieces, shall we?

            nate

            Comment

            • Ben Pope

              #7
              Re: List Iterator Not Incrementable?

              freckred76@hotm ail.com wrote:[color=blue]
              > red floyd,
              >
              > I must admit that I did not write this code. I simply tried compiling
              > it for a friend under 2003, which worked, and 2005, which did not work.
              > I could not see a problem, when of course the problem was very
              > obvious. However, let's not pick it to pieces, shall we?[/color]

              It's sometimes difficult to accept criticism, and if you post code to
              this group it WILL be criticised heavily, but then, that's what you're
              asking for. Learn from the criticism, don't take it personally.

              Ben Pope
              --
              I'm not just a number. To many, I'm known as a string...

              Comment

              • Stephan Brönnimann

                #8
                Re: List Iterator Not Incrementable?

                freckred76@hotm ail.com wrote:[color=blue]
                > Hi,
                >
                > I think this might be a VC++ problem. I am using Microsoft Visual
                > Studio 2005 Full Version (8.0).
                >
                > I have a simple for loop that iterates over a list using the standard
                > iterator. The list is populated with a struct _BLOCK defined as:
                >
                > typedef struct
                > {
                > int iX ;
                > int iY ;
                > int iFrame ;
                > double dIntensity ;
                > } _BLOCK ;
                >
                > std::list<_BLOC K> list_block;
                > std::list<_BLOC K>::iterator list_block_it;
                >
                > for (list_block_it = list_block.begi n (); list_block_it !=
                > list_block.end (); list_block_it++ )
                > {
                > list_block_it->dIntensity -= 0.025 ;
                > if (list_block_it->dIntensity < 0.0)
                > { // Delete this item[/color]
                Rather than this obvious comment ...
                .... I'd expect a rationale why the next element in the list is not
                tested.
                [color=blue]
                > list_block_it = list_block.eras e (list_block_it) ;
                > }
                > }
                >
                > The code seems fine to me, but it always fails an assert at run-time,
                > claiming "list iterator not incrementable." I haven't been able to
                > find any documentation or threads about this problem. Also, it seems
                > like this code runs fine when built with g++ or previous versions of
                > VC++.
                >
                > Any help is greatly appreciated,
                >
                > Nate[/color]

                The correct way to remove element from a sequence is:
                typedef std::list<int> List; // just a short-hand
                typedef List::iterator Iter; // just a short-hand

                List list;
                for (Iter i = list.begin(); i != list.end();) {
                if (*i < 0) i = list.erase(i);
                else ++i;
                }

                Regards, Stephan

                Comment

                • Michiel.Salters@tomtom.com

                  #9
                  Re: List Iterator Not Incrementable?


                  freckred76@hotm ail.com wrote:[color=blue]
                  > red floyd,
                  >
                  > I must admit that I did not write this code. I simply tried compiling
                  > it for a friend under 2003, which worked, and 2005, which did not work.[/color]

                  The VC2005 compiler is improved (duh). It catches many errors
                  immediately
                  whereas with the VC2003 compiler you would have other problems later
                  on.[color=blue]
                  >From experience, we prefer the VC2005 behavior. You can catch it before[/color]
                  the boss is looking ;)

                  Michiel.

                  Comment

                  Working...