Hi,
I'm trying to 'reduce' a vector using the erase algorithm within a for loop.
The idea is to scan a table looking for equal successive elements. Once equal elements are found, it erases one of the 2 elements. I'm suspecting a problem in the for loop, due to the iterator. What happens to it's value once an element is deleted ?

void faisceau::reduction(int div)
      {
       
        //if (div!=1)
          {    
          std::vector<photon>::iterator iter, itertracker=((*this).tab_photon).begin();     
           for(iter=itertracker; iter!=((*this).tab_photon).end();iter++)
           if ( ((*iter).tps_arrive) == ((*(iter+1)).tps_arrive)  )
                {
	          ((*iter).ponderation)++;
                  ((*this).tab_photon).erase(iter+1);
                  itertracker=iter;
                }
          }   
      }

I found this on a web:

Because vectors keep an array format, erasing on positions other than the vector end also moves all the elements after the segment erased to their new positions,
This invalidates all iterator and references to elements after position or first.

Recommended Answers

All 6 Replies

>>What happens to it's value once an element is deleted ?
The iterator is invalidated and you have to start it all over again. Example here: The program will crash after the erase() is executed unless the break statement is there to stop the loop.

#include <vector>
#include <iostream>
#include <string>
#include <iomanip>
using namespace std;

int main()
{
    vector<int> array;
    int i;
    for(i = 0; i < 10; i++)
        array.push_back(i);
    vector<int>::iterator it = array.begin();
    for(i = 0; it != array.end(); it++, i++)
    {
        if(i == 5)
        {
            array.erase(it);
            break;
        }
        cout << *it << "\n";

    }
    cout << "\n";
    for(it = array.begin(); it != array.end(); it++)
    {
        cout << *it << "\n";
    }
	return 0;
}

Okay, I understood that.
And what if I write :

bool b2=false;
           while(b2==false)
           {
              for(iter=itertracker; iter!=((*this).tab_photon).end();iter++)
              if ( ((*iter).tps_arrive) == ((*(iter+1)).tps_arrive)  )
                   {
	             ((*iter).ponderation)++;
                     ((*this).tab_photon).erase(iter+1);
                     itertracker=iter;
                     break;
                   }
              if((itertracker)==( ((*this).tab_photon).end()  )) b2=true;  
           }

will this work ?

>>will this work ?
Maybe -- try it and find out what it will do.

I admit my question was silly! :confused:
I tried it, but it didn't work.
Actually, it compiles, but then the pc starts WORKING HARD(calculating?), and don't stop until I force it to quit.
Would you please help me find the error?

if you want to iterate through a sequence container erasing elements as you go along, you must use the return value of container::erase . the return value is a vald iterator that designates the first element remaining beyond element(s) erased, or end if no such element exists. for example, the following will erase all even numbers from the vector.

std::vector<int> vec(100) ;
  for( int i=0 ; i<vec.size() ; ++i ) vec[i] = i ;
  std::vector<int>::iterator iter = vec.begin() ; 
  while( iter != vec.end()  )
  {
    if( ( *iter % 2 ) == 0 ) iter = vec.erase( iter ) ;
    else ++iter ;
  }

to remove duplicate elements that are adjacent to each other in a specified range, you can use the algorithm std::unique . for example, this will erase adjacent duplicate elements from the vector.

std::vector<int> vec(100) ;
  for( int i=0 ; i<vec.size() ; ++i ) vec[i] = i/10 ;
  vec.erase( std::unique( vec.begin(), vec.end() ), vec.end() ) ;
commented: Gread explaination -- I learned something too today :) +25

Beautiful!
Thanks a LOT.
:*

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.