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

J

John Black

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!
 
V

Victor Bazarov

John said:
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
 
J

John Harrison

John Black said:
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
 
D

Dave Townsend

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
 
J

Jeff Flinn

John Black said:
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
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,768
Messages
2,569,575
Members
45,053
Latest member
billing-software

Latest Threads

Top