-5

This is the edited code

vector<vector<int> > vec; 
vector<vector<int> >::iterator vit; 
vector<int>::iterator it;
for ( vit = vec.begin(); vit != vec.end(); ++vit)
{
    it = vit->begin();
    while(it != vit->end()) 
    {
        while(it != vit->end())
        {

            if( condition )
            {
                while( condition )
                {
                    //going back to certain it
                    //erase an element
                    it  = vit->erase(it);
                }
            }
            else
                ++it;
        }
        ++it;
    }
}

The inner while loops back to certain point. Link missing. Erasing element without copying iterator and without memory leakage in back loop and again forward?

Raghu G
  • 87
  • 4
  • 1
    `while(it < vit->end())` - This is a bug already. – IInspectable Apr 12 '16 at 10:29
  • 2
    Possible duplicate of [How to delete an element from a vector while looping over it?](http://stackoverflow.com/questions/8597240/how-to-delete-an-element-from-a-vector-while-looping-over-it) – Pixelchemist Apr 12 '16 at 10:32

4 Answers4

6

If you want to remove certain elements of the inner vectors use the erase-remove idiom on them:

for (auto & intv : vec)
{
  intv.erase( 
    std::remove_if( intv.begin(), intv.end(), 
      [](int value) -> bool { return value == 2; }), 
    intv.end() );
}

Notes:

  1. You can apply certain conditions depending on vec or other local variables by capturing them in the lambda expression.

  2. This example would remove all elements from the inner vectors that are equal to 2.

  3. For int it is preferable to pass the lambda paramter by value. For bigger objects you'd probably want to have a const reference lambda paramter.

Pixelchemist
  • 24,090
  • 7
  • 47
  • 71
3

You can use the erase-remove idiom for that purpose.

Simple example:

#include <iostream>
#include <vector>
#include <algorithm>

bool is_odd(const int &i)
{
    return (i % 2) != 0;  
}

int main() 
{
    std::vector<int> v = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
    // removes all odd numbers
    v.erase(std::remove_if(v.begin(), v.end(), is_odd), v.end());
    for(const auto &i:v)
    {
        std::cout << i << ' ';
    }
    return 0;
}

Of course you can achieve the same thing using a lambda like this:

#include <iostream>
#include <vector>
#include <algorithm>

int main() 
{
    std::vector<int> v = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
    // removes all odd numbers
    v.erase( std::remove_if(v.begin(), v.end(),
        [](const int &i) -> bool {return (i % 2) != 0;}),
        v.end() );
    for(const auto &i:v)
    {
        std::cout << i << ' ';
    }
    return 0;
}
Mayhem
  • 487
  • 2
  • 5
  • 13
1

You can use STL vector's erase function. Just use vector.remove(*it) to remove the element

N6t9N
  • 21
  • 3
0

You dont need to worry about memory leaks, in your case you use std::vector which uses RAII to make sure no memory is leaked. With STL containers you can "leak" in such case on;y if you do not shrink your vector after using remove algorithm.

Below is fix to your code, and not entire rewrite. This code removes all values equal to 1 [LIVE]:

vector<vector<int> > vec = { {0,1,2,3}, {0,1,2,3,4,5}, {0,1} }; 
vector<vector<int> >::iterator vit = vec.begin(); 
vector<int>::iterator it;

while(vit != vec.end()) {
    it = vit->begin();
    while(it != vit->end()) {
     if( *it == 1 ) {
        it = vit->erase(it);

         // Not sure why you want this loop here
         //while( condition )
         //{
         //     **erase an element;**
         //}
     }
     else {
       ++it;
     }
    }
    ++vit;
}  

for (auto it1 = vec.begin(); it1 != vec.end(); ++it1){
    for (auto it2 = it1->begin(); it2 != it1->end(); ++it2)
       std::cout<<*it2<< ", ";
    std::cout << "\n";
}

produces:

g++ -std=c++14 -O2 -Wall -pedantic -pthread main.cpp && ./a.out
0, 2, 3, 
0, 2, 3, 4, 5, 
0, 
marcinj
  • 48,511
  • 9
  • 79
  • 100
  • Thanks. The inner 'while' loops back to certain point while going back elements are erased on a condition. There is a problem in going backward and forward again, missing links. – Raghu G Apr 12 '16 at 12:08
  • @RaghuG I probably dont understand, but you can reassign `it` to new iterator, as long as it is in the range of the vector on which it operates. In my example you can assign `it` back to `vit->begin()`, then iterate it again in your inner loop, or better use another iterator. – marcinj Apr 12 '16 at 12:22
  • Marcin Jędrzejewski Thank you. Solved problem by assigning new iterator. – Raghu G Apr 12 '16 at 14:57