Skip to main content
GameDev.net gamedev.net
🔒 Locked

[STL] std::map erasing elements and size

Started by gimp Jul 30, 2002 at 10:26 PM 7 replies 350+ views
Original Post
gimp
gimp
I have a resource manager that at it''s core uses an stl map to store resources. When an object''s ref count reaches zero I .erase() the element. When my application ends as a sanity check I''d like to check to ensure all resources are already released. I cannot check the .size() or .empty() as the elements are merely cleaned but the nodes remain. How do I move forward here to ensure that all my resources really are released? What can I check in the map? Many thanks, Chris Brodie http:\\fourth.flipcode.com
Chris Brodie
TangentZ
TangentZ
Why can''t you just check for an empty map? I''m not sure I
understand the problem here. Perhaps you can elaborate more.

Naturally, I''m assuming that your resource manager has a
longer lifetime than any of the allocated resources.



Kami no Itte ga ore ni zettai naru!
神はサイコロを振らない!
gimp
gimp
Yes, the resource manager is a singleton. I do the check in the resource managers dtor which in turn is called by the Singleton::ReleaseInstance().

Unless I have an error elsewhere in my resource releasing code(which ''appears'' to be operating normally) then this has to be it. My map''s ''size'' is 12 and empty returns false. I would have thought that if I inserted 12 elements then used those same 12 iters that were returned in an erase call the size would be 0, but that doesn''t seem to be the case. Mind you if this -SHOULD- be the case then I''ll go bug hunting in the resource releasing code. Here is some more info:


  
//Here is my resource container.

std::map<std::string, std::pair<boost::shared_ptr<ResourceType>, size_t> > m_Resources;

//Resource releasing (The handle only gets an iter to the resource

--(a_Handle.GetResource()->second.second);
if (a_Handle.GetResource()->second.second == 0)
m_Resources.erase(a_Handle.GetResource());



I can post the whole thing if needed.

Chris Brodie
http:\\fourth.flipcode.com
Chris Brodie
TangentZ
TangentZ
Ouch, the templated code confused me for a second.second there.
Oops, forget the second second, it shouldn''t be there.

The release code itself looks OK. But the question then
becomes, is it being called? The right number of times?



Kami no Itte ga ore ni zettai naru!
神はサイコロを振らない!
Shannon Barber
Shannon Barber
quote:
Original post by gimp
I cannot check the .size() or .empty() as the elements are merely cleaned but the nodes remain.


You must transverse the entire map and perform some check on each node then.

If you call erase on the key, the map node is removed - if this is the case, everything in the map is a leak.

The trade-off between price and quality does not exist in Japan. Rather, the idea that high quality brings on cost reduction is widely accepted.-- Tajima & Matsubara
gimp
gimp
"Oops, forget the second second, it shouldn''t be there."

???
.first is the string index
.second is the ''resource pair''.
.second.first is the shared pointer
.second.second is the reference count. (I would like to use the shared pointer ref count but I''m not actualy taking a ref count and shared_ptr has no means for me to tell it the count. But this is a side issue)

I have made an assumption here that a std:air will call the dtor of it''s two members on descruction.


I''m sure some kind of deallocation is taking place as I debug step through the erase line but the size doesn''t decrease...???

Chris Brodie
http:\\fourth.flipcode.com
Chris Brodie
TangentZ
TangentZ
quote:
Original post by gimp
"Oops, forget the second second, it shouldn''t be there."

???



Pardon my poor attempt at poking fun at the "second.second"
situation happening in the code. Yes, I know it''s the
correct syntax and everything. It just looks funny.

Yes, when the pair is destroyed, the two things inside
disappear also.

I assume that you have a pair of functions:


void AcquireResource(const string &Key);
void ReleaseResource(const ResourceHandle &Handle);


For the whole system to work correctly, you must make sure
the calls are balanced. One Release for each Acquire.

Hmm... map::erase() should cause the size to go down. At
least when I use it...



Kami no Itte ga ore ni zettai naru!
神はサイコロを振らない!
shurcool
shurcool
i''m not sure if this is correct (in your situation) because it seems to be so simple, but why don''t you check the size_t variable? if it''s 0, then the resource is released. otherwise not.

---
shurcool
wwdev
sark
sark
quote:

(I would like to use the shared pointer ref count but I''m not actualy taking a ref count and shared_ptr has no means for me to tell it the count. But this is a side issue)



It seems you are over-complicating your entire resource system. Why not let boost::shared_ptr take care of all your reference counting?


  

class MyResource
{
public:
void CreateMyResource()
{
m_pRefCounted = boost::shared_ptr<MyReferenceCountedData>( new MyReferenceCountedData );
}

// default copy constructor and assignment operator member-by-member copy copies m_pRefCounted properly


private:
struct MyReferenceCountedData
{
MyReferenceCountedData()
{
// stuff that gets called once, on creation of resource

}
~MyReferenceCountedData()
{
// stuff that gets called once, on destruction of resource

}
}

boost::shared_ptr<MyReferenceCountedData> m_pRefCounted;
};



No need for messy singletons or keeping your own reference count.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.