Sign in to follow this  
KevArnold

C++: Deleting objects in containers

Recommended Posts

My Engine class loads and manages resources loaded by my Game and Menu(s) class. Resources are added to stl::containers by name so they are only loaded once. All of my Menus live for the life of the Engine so their resources are not freed until the Engine exits. The Games resources are freed between levels.

The problem I am having is I recently added some sounds that I want to use in a Menu and in the Game. The problem is when the Game exits it wants to destroy the resource so when the Menu comes up their is a crash. I could just load the resource twice but if possible I'd like to improve my programming skills and solve this problem more elegantly.

I looked at shared_ptr offered by Boost and this seems to be a good solution for sharing pointers between the Game and Menu class. The problem though is the destructor is never called and I think it is because the objects are stored in containers.

Is my design fundamentally flawed or is there a way to add shared_ptrs to a list without increasing the reference count? If I don't increase the reference count when adding it to a list is that just a bad hack?

Share this post


Link to post
Share on other sites
Is the order of events:
Game created (sound loaded)
Game destroyed (sound destroyed)
Menu created
Crash?

Reference counting would not work in your case since the game is being destroyed before the menu is being created which would mean that the reference could would go to 0.

The easiest and possibly the best solution is to create a new container that contains 'Game Wide' resources. These resources would stay loaded throughout the duration of the whole game. You could pass a reference to this to both Menu and Game when they are created.

Quote:

Is my design fundamentally flawed or is there a way to add shared_ptrs to a list without increasing the reference count? If I don't increase the reference count when adding it to a list is that just a bad hack?

Sounds hacky and dubious. The purpose of shared_ptr is to automatically destroy your object when it runs out of reference. If you use a way to avoid increasing the reference could (there are ways) you are risking deferencing a freed object.

p.s. I'd call your 'Game' class 'Level' if it's scoped to a level.

Share this post


Link to post
Share on other sites
Quote:
Original post by stevenmarky
Quote:

Is my design fundamentally flawed or is there a way to add shared_ptrs to a list without increasing the reference count? If I don't increase the reference count when adding it to a list is that just a bad hack?

Sounds hacky and dubious. The purpose of shared_ptr is to automatically destroy your object when it runs out of reference. If you use a way to avoid increasing the reference could (there are ways) you are risking deferencing a freed object.

p.s. I'd call your 'Game' class 'Level' if it's scoped to a level.


Actually, what he's describing is weak_ptr, which is a very common approach to resource management. If you keep a list of weak_ptr's, what'll happen is the resources will be deleted once they're no longer in use anywhere outside the list, and the weak_ptr to them will be set to a state that indicates the pointee has been deleted.

Look up weak_ptr in the boost documentation (right alongside with shared_ptr there), to see if you think that suits your needs.

Share this post


Link to post
Share on other sites
Quote:
Original post by Shinkage
Quote:
Original post by stevenmarky
Quote:

Is my design fundamentally flawed or is there a way to add shared_ptrs to a list without increasing the reference count? If I don't increase the reference count when adding it to a list is that just a bad hack?

Sounds hacky and dubious. The purpose of shared_ptr is to automatically destroy your object when it runs out of reference. If you use a way to avoid increasing the reference could (there are ways) you are risking deferencing a freed object.

p.s. I'd call your 'Game' class 'Level' if it's scoped to a level.


Actually, what he's describing is weak_ptr, which is a very common approach to resource management. If you keep a list of weak_ptr's, what'll happen is the resources will be deleted once they're no longer in use anywhere outside the list, and the weak_ptr to them will be set to a state that indicates the pointee has been deleted.

Look up weak_ptr in the boost documentation (right alongside with shared_ptr there), to see if you think that suits your needs.


But if his order of events is what I thought it is in my first post, there will be no referenced resources after the Game has been destroyed, and Menu would have to reload the sound upon receiving a null pointer from the weak_ptr - which is what he is trying to avoid. Am I missing something?

Share this post


Link to post
Share on other sites
Quote:
Original post by stevenmarky
Is the order of events:
Game created (sound loaded)
Game destroyed (sound destroyed)
Menu created
Crash?


The order of events is:

1) Engine
2) Load/Show Main Menu
3) Load/Show Game
4) Delete Game - deletes sound shared with Main Menu
5) Show Main Menu (sound deleted so crash)

I'm currently trying to better understand weak_ptrs, thanks for the tip.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this