STL vector and erase : HELP

M

mosfet

Hi,

I have a vector of type TReferenceItem(structure) and I would like to erase
one of the TReferenceItem inside the vector based on 2 criteria of the
TReferenceItem

vector<TReferenceItem>::iterator itVec;

for ( i = 0, itVec = m_RefItemVec.begin() ; itVec != m_RefItemVec.end();
itVec++, i++)
{
nCompIDServer = memcmp(m_RefItemVec.IDServer, AIDServer,
sizeof(TARSIDServer));
nCompIDUser = (m_RefItemVec.IDUser == AIDUser)?0:1;

if (nCompIDServer == 0 && nCompIDUser == 0) // If the 2 criteria match
{
m_RefItemVec.erase(itVec); // Delete the reference
}

}

Actually my problem is simple I whant to get through each element of my
vector and if the element match my conditions I want to remove it.



I tried the above code but it doesn't work because if the TReferenceItem to
remove is the last element when i do : m_RefItemVec.erase(itVec) the
iterator.end is modifief so that my stop condition is never realized and i
have a forever loop.
What is the solution ?
 
M

mosfet

I tried also this and it is not better :

for (itVec = m_RefItemVec.begin() ; itVec != m_RefItemVec.end(); ++itVec)
{
AfxMessageBox( _T("LOOP") );
nCompIDServer = memcmp((*itVec).IDServer, AIDServer,
sizeof(TARSIDServer));
nCompIDUser = ((*itVec).IDUser == AIDUser)?0:1;
if (nCompIDServer == 0 && nCompIDUser == 0) // If the 2 criteria match
{
AfxMessageBox( _T("I have deleted") );
m_RefItemVec.erase(itVec); // Delete the reference
}

}
 
I

Ivan Vecerina

| I have a vector of type TReferenceItem(structure) and I would like to
erase
| one of the TReferenceItem inside the vector based on 2 criteria of the
| TReferenceItem
|
| vector<TReferenceItem>::iterator itVec;
|
| for ( i = 0, itVec = m_RefItemVec.begin() ; itVec != m_RefItemVec.end();
| itVec++, i++)
| {
[...] if( ... some condition ... )
| {
| m_RefItemVec.erase(itVec); // Delete the reference
| }
| }

This loop not only leads to UB if the last item is removed,
but it will fail to remove the second of two consecutive
items to be removed.

Also, the approach you are using to test the condition seems
incorrect:
| nCompIDServer = memcmp(m_RefItemVec.IDServer, AIDServer,
| sizeof(TARSIDServer));
| nCompIDUser = (m_RefItemVec.IDUser == AIDUser)?0:1;
You should use (*itVec) instead of m_RefItemVec,
because once you remove an entry the index of all the
following items will be shifted...



| What is the solution ?

When an item is removed, the iterator shall not be incremented.
So the correct code is:
for( it = vec.begin() ; it != vec.end() ; /*empty*/ )
if( needToRemove(*it) )
vec.erase( it );
else
++it;


Also, you should consider using the standard remove_if
from header <algorithm>:
vec.erase( remove_if( vec.begin(), vec.end(), RemoveTest() )
, vec.end() );
Where RemoveTest needs to be a predicate (a unary function object).
It would be a good idea to learn about this.
See for example:
http://www.sgi.com/tech/stl/functors.html
or other references discussed in this NG...


I hope this helps,
Ivan
 

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,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top