1,105,386 Community Members

vector::erase

Member Avatar
adnanius
Newbie Poster
16 posts since Mar 2008
Reputation Points: 0 [?]
Q&As Helped to Solve: 0 [?]
Skill Endorsements: 0 [?]
 
0
 

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.

Member Avatar
Ancient Dragon
Achieved Level 70
27,645 posts since Aug 2005
Reputation Points: 5,232 [?]
Q&As Helped to Solve: 3,038 [?]
Skill Endorsements: 115 [?]
Team Colleague
Featured
Sponsor
 
0
 

>>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;
}
Member Avatar
adnanius
Newbie Poster
16 posts since Mar 2008
Reputation Points: 0 [?]
Q&As Helped to Solve: 0 [?]
Skill Endorsements: 0 [?]
 
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 ?

Member Avatar
Ancient Dragon
Achieved Level 70
27,645 posts since Aug 2005
Reputation Points: 5,232 [?]
Q&As Helped to Solve: 3,038 [?]
Skill Endorsements: 115 [?]
Team Colleague
Featured
Sponsor
 
0
 

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

Member Avatar
adnanius
Newbie Poster
16 posts since Mar 2008
Reputation Points: 0 [?]
Q&As Helped to Solve: 0 [?]
Skill Endorsements: 0 [?]
 
0
 

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?

Member Avatar
vijayan121
Posting Virtuoso
1,769 posts since Dec 2006
Reputation Points: 1,097 [?]
Q&As Helped to Solve: 329 [?]
Skill Endorsements: 16 [?]
 
1
 

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() ) ;
Member Avatar
adnanius
Newbie Poster
16 posts since Mar 2008
Reputation Points: 0 [?]
Q&As Helped to Solve: 0 [?]
Skill Endorsements: 0 [?]
 
0
 

Beautiful!
Thanks a LOT.
:*

Question Answered as of 6 Years Ago by Ancient Dragon and vijayan121
You
This question has already been solved: Start a new discussion instead
Post:
Start New Discussion
Tags Related to this Article