deleting the contents of a std::map

Started by
10 comments, last by sipickles 18 years, 3 months ago
Hello! Nice xmas theme..... I have a puzzle over the best way to delete the contents of a std::map, in MSVC2003 Using a std::vector, I normally iterate thru the vector, SAFE_DELETEing, then do a .clear(); I tried this: std::map< int, cProxyObject*, std::less<int> >::iterator iter; for ( iter = m_objectList.begin(); iter != m_objectList.end(); ++iter ) delete *iter; m_objectList.clear(); but it doesnt like the delete *iter; line. Any suggestions gratefully appreciated! Si
Advertisement
*iter is a std::pair<int, cProxyObject*>.

The line needs to be:
delete iter->second;
Haven't messed with C++ in a while, but...

the pointer is sitting at the value portion in the map. so you would want to do

delete iter->second
FTA, my 2D futuristic action MMORPG
Of course you can save yourself some headaches by using a map of smart pointers or possibly boost::ptr_map.
Following up on this subject, I have now come across a further problem. Here's my code:

for ( iter = m_objectList.begin(); iter != m_objectList.end(); ++iter )
{
SAFE_DELETE( iter->second );
//m_objectList.erase( iter );
g_log->Log( L"%d objects remaining\n", m_objectList.size() );
}

This is a puzzle. The code successfully deletes all the objects stored in iter->second, but the m_objectList still contains NULLed entries.

Okay, so by uncommenting the above line, the m_objectList.size() reflects only the undeleted objects. Seems greats but......

Unfortunately, by using .erase() I seem to be mucking up the iterator loop. How can I loop though something which I am deleting!!!

I tried:
m_objectList.erase( iter->first );
but same results.

Thanks in advance

Simon
Quote:Original post by sipickles
Unfortunately, by using .erase() I seem to be mucking up the iterator loop. How can I loop though something which I am deleting!!!


This just came up here, but it was for a list, so for a map, it's still the same logics [wink]
iter = m_objectList.begin();while(iter != m_objectList.end()){   SAFE_DELETE( iter->second );   m_objectList.erase( iter );   g_log->Log( L"%d objects remaining\n", m_objectList.size() );   iter = m_objectList.begin();}

That's it! Of course if you look further down the page on that last link, SiCrane suggests just calling clear at the end rather than try to delete as you go - which is the best thing to do, unless you are not erasing all the tiems in the map. For example, you would want to use my code if you had:

iter = m_objectList.begin();while(iter != m_objectList.end()){   SAFE_DELETE( iter->second );   m_objectList.erase( iter );   g_log->Log( L"%d objects remaining\n", m_objectList.size() );   if(objectList.size() % 2 == 0)      break;   iter = m_objectList.begin();}

In which case, you definitly don't want to call clear at the end. [wink]
If you are going to erase as you go you might as well do:
while (!m_objectList.empty()){   SAFE_DELETE(m_objectList->begin()->second);   m_objectList.erase(m_objectList.begin());   g_log->Log( L"%d objects remaining\n", m_objectList.size() );}


As Drew says above, it would probably be faster to delete them and then clear at the end. I haven't looked at how they code clear() but hopefully it isn't by iteratoring through each one and deleting them one at a time (while relinking everything)
But what if you only want to delete some of them?

[edit - add code for delete_if_we_should. :P]

bool delete_if_we_should(iterator I){   if (some_test_involving_I)    {       delete I->second;       return true;   }   return false;}for (iterator I = container.begin(); I != container.end(); ){   if (delete_if_we_should(I)) I = container.erase(I);   else ++I;}
Quote:Original post by Deyja
But what if you only want to delete some of them?

for (iterator I = container.begin(); I != container.end(); ){   if (delete_if_we_should(I)) I = container.erase(I);   else ++I;}


In a map, erase doesn't return an iterator.

for (iterator I = container.begin(); I != container.end(); ){   if (delete_if_we_should(I))   {       iterator nextI = I; nextI++;       container.erase(I);       I = nextI;   }   else ++I;}
Quote:Original post by SiCrane
Of course you can save yourself some headaches by using a map of smart pointers or possibly boost::ptr_map.


You see this post? These are some of the headaches you could have saved.

This topic is closed to new replies.

Advertisement