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

STL vector and erase : HELP

P: n/a
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[i].IDServer, AIDServer,
sizeof(TARSIDServer));
nCompIDUser = (m_RefItemVec[i].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 ?
Jul 19 '05 #1
Share this Question
Share on Google+
2 Replies


P: n/a
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
}

}

"mosfet" <tr******@wanadoo.fr> a écrit dans le message de
news:bp**********@news-reader3.wanadoo.fr...
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[i].IDServer, AIDServer,
sizeof(TARSIDServer));
nCompIDUser = (m_RefItemVec[i].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 ?

Jul 19 '05 #2

P: n/a
"mosfet" <tr******@wanadoo.fr> wrote in message
news:bp**********@news-reader3.wanadoo.fr...
| 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[i].IDServer, AIDServer,
| sizeof(TARSIDServer));
| nCompIDUser = (m_RefItemVec[i].IDUser == AIDUser)?0:1;
You should use (*itVec) instead of m_RefItemVec[i],
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
--
http://ivan.vecerina.com
Jul 19 '05 #3

This discussion thread is closed

Replies have been disabled for this discussion.