Question on boost::shared_ptr

Started by
17 comments, last by phresnel 15 years, 1 month ago
Does shared_ptr automatically clean up the data when the program exits? I'm using Visual Leak Detector to plug up my memory leaks and I have left shared_ptrs with reference counts on them when exiting the program and VLD doesn't show any leaks. Just wondering if VLD has a problem with boost and detecting used memory.
Advertisement
What do you exactly mean by "left shared_ptrs with reference counts on them"?
As long as your shared_ptr objects are created on the stack they will have been destroyed at program exit, thus decreasing their reference counters and freeing up the allocated memory. I suspect VLD would have no problem detecting these since shared_ptr uses the delete operator to deallocate memory.

If you have created shared_ptr objects on the heap and they are still around when the program exits then you would have a leak, but that would just be strange use of shared_ptr.
Hack my projects! Oh Yeah! Use an SVN client to check them out.BlockStacker
Maybe declaring static shared_ptrs would report as leaks too.
For example the _CrtDumpMemoryLeaks(); method reports static strings in my application as leaks but they are freed after the process ends.
This is my first time really using boost so I might be just being dumb about it.

But my game has a model class that stores the model data for each entity. Entities can share models so I went with the shared_ptr so I wouldn't have to worry about the memory management. When the entities are being created they ask for the model and the model manager keeps a internal std::map to each model type loaded in so far. When the entity gets destroyed it calls reset on the model pointer to decrease the reference count. Now to completely free the memory I also need to clear the std::map holding the master model list. I have skipped that on purpose so the model data should never be removed from memory when the game is exited. This is where I thought VLD should be giving me a memory leak error but it doesn't it.

The original instance of each shared_ptr is getting newed (ie Model model = Model(new CModel(m_D3DDevice...))) so they should be created on the heap. So I would think VLD would be tracking it and seeing that the memory doesn't get freed.

I should note that I do have another class that actually creates and maintains the list of models and that the std::map is a private member to that class. And that class gets deleted at shutdown.
If you are storing all models in a map like this :
std::map<std::string,boost::shared_ptr<Model>> models;

And if this is stored under the model manager which is on the stack,then when the model manager goes out of scope all the models will be freed(if all entities holding references go out of scope too.)
If the model manager is also on the heap then you either have to delete it or wrap the model manager in a shared_ptr too.
Also you don't have to call .reset manually.The memory is freed when all shared_ptrs goes out of scope.
You probably know this but just to clarify, use shared_ptr like so:

{  // Create new object  boost::shared_ptr<MyClass> ptr = new MyClass();  // Operate on object  ptr->myFunction();  // Now the shared_ptr goes out of scope and is destroyed.  // Reference count is automatically decremented.  // Since the count was 1 the object will be auto-deleted.}


If you haven't already, check out the documentation for boost::shared_ptr. Especially, read through the Best Practices section since it highlights a possible memory leak that can occur if you're not careful.
Hack my projects! Oh Yeah! Use an SVN client to check them out.BlockStacker
Alternatively you can give the allocation to the constructor of the shared_ptr like this :

boost::shared_ptr<SomeClass> foo(new SomeClass());
The code in staaf's example would initialize the shared_ptr via its constructor, too, even though it looks like an assignment.


EDIT: Reworded statement to remove potential ambiguities.


EDIT2: Damn! nullsquared is correct. That wouldn't actually compile at all.

[Edited by - Red Ant on March 4, 2009 10:22:35 AM]
Do you have any cycles ? If class A maintains a shared pointer to B and B also looks back at A - then a cycle exists and it will prevent release of the AB group when another pointer holding onto A or B releases. I've found it is easy to inadvertently create cycles when using shared_ptrs as the this argument of boost::bind for event handlers. Another problem case is a tree where nodes maintain reference counted parent links.

This topic is closed to new replies.

Advertisement