std::map help

Started by
9 comments, last by taby 17 years, 9 months ago
I'm using a map to store an ID and a pointer to an abstract resource class. Every resource provides a Release( ) function and I want a ReleaseAll( ) function that loops through the map and calls the Release( ) method of each resource and then deletes the pointer to the resource. Heres my attempt:

typedef std::map< int, Resource* > IDResourceMap;

ReleaseAll( )
{
	IDResourceMap::iterator it = 0;

	for( IDResourceMap::iterator it = m_ResourceMap.begin( ) ; it != m_ResourceMap.size( ) ;  it++ );
	{
		Resource* pResource = (*it).second;
		pResource->Release( );
		delete pResource;
	}
}
However I keep getting unhandled exceptions calling Release( ) because the pointer is NULL. If I load one resource and insert its pointer and id into the map the maps size becomes one but then when looping I end up with NULL pointers. Could someone point out how I'm supposed to do this with a std::map? :p Thanks.
Advertisement
I would suspect it's due to this part of the for loop
it != m_ResourceMap.size( )

change it to
it != m_ResourceMap.end()
Another thing is that you never remove the actual entries in the map. I'd suggest to call IDResourceMap.clear() at the end of ReleaseAll.
How on Earth does this even compile? Which standard library implementation allows one to compare with and assign integers to a std::map iterator?
You are not looping properly.

Change:
for(IDResourceMap::iterator it = m_ResourceMap.begin(); it != m_ResourceMap.size(); it++);

to

for(IDResourceMap::iterator it = m_ResourceMap.begin( ) ; it != m_ResourceMap.end(); it++)

Error 1: You were terminating using a non-iterator, this is no good. Use .end()

Error 2: You had an extra ; at the end of the loop header. This will cause nothing to occur during looping. Only once the iterator is past the end do you try to access the map. This is obviously a problem.
Whoops I never meant to do that. [smile]

This is what I meant to post:
	for( IDResourceMap::iterator it = m_ResourceMap.begin( ) ; it != m_ResourceMap.end( ) ;  it++ )	{		Resource* pResource = (*it).second;		pResource->Release( );		delete pResource;	}	m_ResourceMap.clear( );


@Sharlin

VS's one? [smile]

@taby

Oops :p
Even better yet - change the code to
namespace {   // define a custom deleter that releases the client   template<class T>   inline void release( T * client ) {       std::assert( client != 0 );       client->Release();       delete client;   }}// define a smart pointer type for resourcestypedef boost::shared_ptr<Resource>  ResourcePtr;// use a map of smart pointer valuestypedef std::map< int, ResourcePtr > IDResourceMap;// when you add a resource, you pass the custom deleter:bool AddResource( int id, Resource * resource ) {     return m_ResourceMap.insert( std::make_pair( id, ResourcePtr( resource, release<Resource> ) ) ).second;}// releasing happens automagically via smart pointervoid ReleaseAll() {    m_ResourceMap.clear();}


Cheers,
Pat.

[edit]Fixed - thanks taby![smile][/edit]

[Edited by - darookie on June 27, 2006 9:08:58 AM]
Don't forget about that extra semi-colon. :)
Quote:Original post by Sharlin
How on Earth does this even compile? Which standard library implementation allows one to compare with and assign integers to a std::map iterator?


Lol you can nullify interators using NULL which is infact just 0.
Quote:Original post by taby
Don't forget about that extra semi-colon parenthesis. :)

Thanks taby [lol]

This topic is closed to new replies.

Advertisement