can not dynamically add element to vector in going over the vector

Discussion in 'C++' started by John Black, May 28, 2004.

  1. John Black

    John Black Guest

    Hi,
    I just found out that in looping the vector, you can not push_back()
    to the vector even in some "safe" cases. Here is the code snippet,

    vector<pair<UINT32, UINT32> >::iterator itr;
    for (itr = vec.begin(); itr< vec.end(); ++itr){

    pair<UINT32, UINT32> p1, p2;
    ... assign value of p1 and p2 ...

    if (..in some condition...){
    vec.push_back(p1);
    vec.push_back(p2);
    vec.erase(itr);
    return 0;
    }
    }

    I think this is a safe dynamic addition to the vector as you can see
    once something is added to the vector, I return from the loop. But from
    the debugger I see that after the first push_back(), the iterator, itr,
    changes. I just can not image why this happens.

    Thanks!
     
    John Black, May 28, 2004
    #1
    1. Advertising

  2. John Black wrote:
    > I just found out that in looping the vector, you can not push_back()
    > to the vector even in some "safe" cases. Here is the code snippet,
    >
    > vector<pair<UINT32, UINT32> >::iterator itr;
    > for (itr = vec.begin(); itr< vec.end(); ++itr){
    >
    > pair<UINT32, UINT32> p1, p2;
    > ... assign value of p1 and p2 ...
    >
    > if (..in some condition...){
    > vec.push_back(p1);
    > vec.push_back(p2);
    > vec.erase(itr);


    Here 'itr' is invalid, most likely.

    > return 0;
    > }
    > }
    >
    > I think this is a safe dynamic addition to the vector as you can see
    > once something is added to the vector, I return from the loop. But from
    > the debugger I see that after the first push_back(), the iterator, itr,
    > changes. I just can not image why this happens.


    Because it most likely cannot be kept the same.

    Victor
     
    Victor Bazarov, May 28, 2004
    #2
    1. Advertising

  3. "John Black" <> wrote in message
    news:...
    > Hi,
    > I just found out that in looping the vector, you can not push_back()
    > to the vector even in some "safe" cases. Here is the code snippet,
    >
    > vector<pair<UINT32, UINT32> >::iterator itr;
    > for (itr = vec.begin(); itr< vec.end(); ++itr){
    >
    > pair<UINT32, UINT32> p1, p2;
    > ... assign value of p1 and p2 ...
    >
    > if (..in some condition...){
    > vec.push_back(p1);
    > vec.push_back(p2);
    > vec.erase(itr);
    > return 0;
    > }
    > }
    >
    > I think this is a safe dynamic addition to the vector as you can see
    > once something is added to the vector, I return from the loop. But from
    > the debugger I see that after the first push_back(), the iterator, itr,
    > changes. I just can not image why this happens.
    >
    > Thanks!
    >


    There's a simple solution, just use integers instead of iterators.

    john
     
    John Harrison, May 28, 2004
    #3
  4. John,

    When you push_back an item in the vector, the iterators potentially
    will be invalid, think of it, the vector might need to reallocate the
    internal storage for the elements, so any pointers/iterators now are
    invalid.
    Perhaps if you "reserve" up front you might not see the invalidation of
    the iterators, but its not something I'd do in production code.

    dave


    "John Black" <> wrote in message
    news:...
    > Hi,
    > I just found out that in looping the vector, you can not push_back()
    > to the vector even in some "safe" cases. Here is the code snippet,
    >
    > vector<pair<UINT32, UINT32> >::iterator itr;
    > for (itr = vec.begin(); itr< vec.end(); ++itr){
    >
    > pair<UINT32, UINT32> p1, p2;
    > ... assign value of p1 and p2 ...
    >
    > if (..in some condition...){
    > vec.push_back(p1);
    > vec.push_back(p2);
    > vec.erase(itr);
    > return 0;
    > }
    > }
    >
    > I think this is a safe dynamic addition to the vector as you can see
    > once something is added to the vector, I return from the loop. But from
    > the debugger I see that after the first push_back(), the iterator, itr,
    > changes. I just can not image why this happens.
    >
    > Thanks!
    >
    >
     
    Dave Townsend, May 28, 2004
    #4
  5. John Black

    Jeff Flinn Guest

    "John Black" <> wrote in message
    news:...
    > Hi,
    > I just found out that in looping the vector, you can not push_back()
    > to the vector even in some "safe" cases. Here is the code snippet,


    Then they are not safe cases.

    >
    > vector<pair<UINT32, UINT32> >::iterator itr;
    > for (itr = vec.begin(); itr< vec.end(); ++itr){


    'itr < vec.end()' is not portable. Use 'itr != vec.end()' Iterators are not
    pointers.

    > pair<UINT32, UINT32> p1, p2;
    > ... assign value of p1 and p2 ...
    >
    > if (..in some condition...){


    Reverse the order and do the erase first.

    > vec.erase(itr);


    You should be ok, as long as you do in fact exit the loop here. Otherwise
    you'd 'itr = vec.erase(itr);' and remove the ++itr from the above for
    statement and do the increment explicitly in an else clause.

    > vec.push_back(p1);
    > vec.push_back(p2);
    > return 0;
    > }
    > }
    >
    > I think this is a safe dynamic addition to the vector as you can see
    > once something is added to the vector, I return from the loop. But from
    > the debugger I see that after the first push_back(), the iterator, itr,
    > changes. I just can not image why this happens.


    A much better approach is:

    typedef vector<pair<UINT32, UINT32> tVec;

    tVec::iterator lItr = std::find_if( vec.begin(), vec.end(), condition_fnc );

    if( lItr != vec.end() )
    {
    // some calcs

    vec.erase( lItr );

    vec.push_back( ... );
    }

    Jeff F
     
    Jeff Flinn, May 28, 2004
    #5
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Replies:
    8
    Views:
    1,998
    Csaba
    Feb 18, 2006
  2. Replies:
    7
    Views:
    598
    Richard Herring
    Jun 13, 2006
  3. HANM
    Replies:
    2
    Views:
    762
    Joseph Kesselman
    Jan 29, 2008
  4. Konrad Hammerer
    Replies:
    14
    Views:
    628
    Jonathan N. Little
    Feb 7, 2008
  5. ted benedict
    Replies:
    3
    Views:
    160
Loading...

Share This Page