By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
445,898 Members | 2,039 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 445,898 IT Pros & Developers. It's quick & easy.

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

P: n/a
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!
Jul 22 '05 #1
Share this Question
Share on Google+
4 Replies


P: n/a
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
Jul 22 '05 #2

P: n/a

"John Black" <bl***@eed.com> wrote in message
news:40***************@eed.com...
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
Jul 22 '05 #3

P: n/a


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" <bl***@eed.com> wrote in message
news:40***************@eed.com...
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!

Jul 22 '05 #4

P: n/a

"John Black" <bl***@eed.com> wrote in message
news:40***************@eed.com...
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
Jul 22 '05 #5

This discussion thread is closed

Replies have been disabled for this discussion.