This question already has answers here:
Closed 13 years ago.
Possible Duplicate:
Should objects delete themselves in C++?
In my application, I'm creating many objects that "own themselves" - in the sense that after they are created and told to "go," only the object itself can determine when it should be deleted.
For example, if I was writing a game, I might have multiple Enemy objects. Only the Enemy object knows when it should die.
As a result, I end up using delete this inside some of the member functions inside the Enemy object. Is this bad form? Is this something I should avoid, and if so, what is the correct way to handle this type of situation?
The thing to be careful of is that if too many member functions have self-deletion as a side effect, it's easy to accidentally use a reference to the object after it's deleted.
One approach to avoid this is to defer the deletion - that is, put the object on a list, and from your game's main loop, delete everything on that list at the start/end of a tick.
Depends on the memory management strategy. There are cases that it really makes sense and it's the correct thing. For instance, in a reference counting system like COM, the object would do a delete this when the refcount gets down to zero.
For example, if I was writing a game, I might have multiple Enemy
objects. Only the Enemy object knows
when it should die.
The enemy object may know when it enters a "dead" state, yes. But that is not necessarily the same as "the object should be deleted".
Think of all the other objects that may have a reference to it? They may at any time attempt to call a function on the Enemy object (say, TakeDamage()), and if the object has been deleted without informing them, you'll probably have a crash. How do they know that the Enemy they're shooting at is dead?
So the Enemy object knows when it is dead, but not when it should be deleted. It does not own itself.
Who does own it then?
The game world may be a good bet. When the enemy dies, it sends a message to the game world saying that it is dead, and the game world could then be responsible for making sure no one holds a pointer to it, and finally, when it is safe to do so, deleting the object.
It seems odd to me, i myself would prefer someone or something getting rid of them. The fear of someone referencing the object is just terrifying to me. It also seems very possible for a "child" method to unknowningly destroy the object. When you return to a higher level method: you're operating on a non-existant object.
It sounds like you're inventing referencing counting, perhaps explicitely use the reference count pattern.
Or have the objects add themselves to a "to be destroyed" list - and you have yourself a garbage collection system.
As long as the Enemies manage all the references to them (eg. list of units, list of units in groups etc.) it's OK (and used quite often).
But if you want to be on the safer side, the Enemies should register themselves for some destruction routine run at some "safe spot" in the program execution (for an example, see QObject::deleteLater() in Qt.
You could use shared_ptrs to objects to have them automatically clean up when no references to them are available anymore.
Or call the destructor on the class.
To be honest you should try to stick away from that. Otherwise you might delete something that is used by something else and finish off by having a really odd result and probably some memory leak with it.
I think that the object should delete its resources in the destructor. Your class should use another class to know when the enemies are dead.
The referring object(s) should do the deletion, and they should do so by asking the object if the conditions for deletion are met. One of the conditions (besides being eliminated from use in the game) are how many other objects still refer to the object. This is something that can be tracked with static reference counting. Generally, if you write it carefully, you might be able to build it in such a way that enemies are only tracked in one place in your game loop. That place will check collisions and other conditions, and when it's ready to delete the object it will not have to ask if deletion is okay because it knows it's the only client, and can safely dereference what it allocated.
Abstractly, I don't think you want an object deleting itself.
What you want to do is create a control structure that retrieves a SIGNAL or message from the object that it's time to "die", in this case, and the control structure will "delete" or take the particular necessary action on the object.
This way, you leave the control of the object existing or not on the control structure, and when everything has a centralized control unit, you prevent potential calls to deleted objects.
Also, remmeber to differentiate between a soldier "dying" as you say, and an object being actually "deleted" from memory. The dying portion, the object itself can accomplish by setting a flag, such as "dead = true." But the deletion of the object from memory should be accomplished by the control structure I'm referring to.
Related
I am having some issues designing the memory management for an Entity-Component system and am having some issues coming up with the detail of the design. Here is what I am trying to do (note that all of these classes except Entity are actually virtual, so will have many different specific implementations):
The Program class will have a container of Entity's. The Program will loop through the Entity's and call update on each of them. It will also have a few SubSystem's, which it will also update on each loop through.
Each Entity will contain two types of Component's. All of them will be owned by a unique_ptr inside the Entity since their lifetime is directly tied to the entity. One type, UpdateableComponent, will be updated when the Entity.update() method is called. The second type SubSystemComponent will be updated from within their respective SubSystem.
Now here are my two problems. The first is that some of the Component's will control the lifetime of their parent Entity. My current idea for this is that Component will be able to call a function parent.die() which would change an internal flag inside Entity. Then after Program finishes looping through its updates, it loops through a second time and removes each Entity which was marked for deletion during the last update. I don't know if this is an efficient or smart way to go about it, although it should avoid the problem of an Entity dieing while its Component's are still updating.
The second issue is that I am not sure how to reference SubSystemComponent's from within SubSystem. Since they are refered to by a unique_ptr from inside Entity, I can't use a shared_ptr or a weak_ptr, and a standard pointer would end up dangling when the Entity owning a component dies. I could switch to a shared_ptr inside the Entity for these, then use a weak_ptr in the SubSystem's, however I would prefer to not do this because the whole point is that Entity completely owns its Component's.
So 2 things:
Can my first idea be improved upon in a meaningful way?
Is there an easy way to implement a weak_ptr sort of functionality with unique_ptr, or should I just switch to shared_ptr and just make sure to not create more than one shared_ptr to the SubSystemComponent's
Can my first idea be improved upon in a meaningful way?
Hard to say without knowing more about the nature of the work being undertaken. For example, you haven't said anything about your use of threads, but it seems your design gives equal priority to all the possible updates by cycling through things in a set sequence. For some things where low latency is important, or there's some useful prioritorisation that would ideally be done, a looping sequence like that isn't good, while other times it's ideal.
There are other ways to coordinate the Component-driven removal of Entities from the Program:
return codes could bubble up to the loop over entities, triggering an erase from the container of Entities,
an Observer pattern or lambda/std::function could allow the Program to specify cleanup behaviour.
Is there an easy way to implement a weak_ptr sort of functionality with unique_ptr,
No.
or should I just switch to shared_ptr and just make sure to not create more than one shared_ptr to the SubSystemComponent's
It sounds like a reasonable fit. You could even wrap a shared_ptr in a non-copyable class to avoid accidental mistakes.
Alternatively - as for Entity destruction above - you could coordinate the linkage between SubSystem and SubSystemComponent using events, so the SubSystemComponent destructor calls back to the SubSystem. An Observer pattern is one way to do this, a SubSystemComponent-side std::function fed a lambda is even more flexible. Either way, the Subsystem removes the SubSystemComponent from its records.
I'm writing a relatively big project in C++ and have a problem with object deletion. The project, to be precise is a roguelike game.
I have a class Npc which is every monster in the game. They are created and stored in a separate class, Storage<Npc>, that is responsible for their management (loading, saving, creation, deletion, etc). Whenever a monster dies, corresponding object npc has to be deleted and destroyed completely. It is not a problem to delete object itself, I just have invoke a method from Storage<NPC>. The problem is that code contains a lot of pointers to this already-dead npc, which are now invalid and trying to use them will cause a lot of issues. For example:
There may be an action he intended to perform before he died.
Tile on which he stood record store a pointer to him.
He may have been involved in some continuous activities, like grappling somebody.
There are a lot of such pointers in the code, so it is nearly impossible to simply track them. What I need is some way to determine that an npc is already dead, and there is no actual object stored on that address, so that parts of code which still have this pointer can adequately react to his death.
I myself have come up with several ideas, but so far none of them seems really good to me:
I could ask Storage<NPC> class if it has an object on such address. The potential problem is that after object deletion, another object may be allocated on the same address, which will cause bugs.
I could notify all locations that could possibly use the invalid pointer. It is a bad idea because number of such locations will increase over time and doing this is a pain.
I could implement some version of smart pointer, but I'm unsure on which one to use.
tl;dr version: I need a solution that will tell me if a pointer points to an object, or it points to a free chunk of memory, or to some other object, allocated after original object deletion.
With the information you provided, what I can suggest is you implement the Observer Pattern.
If there is code that needs to react to the NPC's death, this pattern is the way to go. Code sections having pointer references to your NPC will be notified upon NPC death and null their copy of pointer to NPC and react to the NPC's death however required. The death notification is sent to all observers before the NPC is actually deleted.
With this pattern, you could implement mechanics such as "Hero gains 50 HP for each monster killed", and it's easily scalable.
You can also use Kevin Ballard's suggestion of using shared_ptr if no code needs to actively react to the NPC's death, and just needs to handle the case where the NPC is dead.
How about using weak pointers? If you store the Npc in a std::shared_ptr (C++11, use std::tr1::shared_ptr for C++03), you can then create std::weak_ptrs (C++11 again, use std::tr1::weak_ptr for C++03) that refer to the shared_ptr. When the shared_ptr actually deletes its object, then all the weak_ptrs will be able to figure this out.
Although I have to wonder why you're deleting Npcs that are still being used elsewhere (e.g. that still have actions). If instead of trying to have all these other references discover you've deleted the Npc, you just want the Npc to die once all references disappear, then using a shared_ptr by itself (with no weak_ptr) will work correctly.
One option is to include a reference count in your class. When some other object (a room, for example) is going to hold a pointer to an npc, the room has the responsibility of increasing the npc's reference count. Now, instead of just deleting a dead npc, you flag it as dead (through another new data member if you don't already have the right flag), and only delete if its reference count is zero. The room object also has the responsibility of periodically checking that flag and if it learns the npc is dead, it decrements its reference count (which will cause a post mortem deletion, if the count is now zero).
Generally I follow the Google style guide, which I feel aligns nicely with the way I see things. I also, almost exclusively, use boost::scoped_ptr so that only a single manager has ownership of a particular object. I then pass around naked pointers, the idea being that my projects are structured such that the managers of said objects are always destroyed after the objects that use them are destroyed.
http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Smart_Pointers
This is all great, however I was just bitten by a nasty little memory stomp bug where the owner just so happened to be deleted before objects that were using it were deleted.
Now, before everyone jumps up and down that I'm a fool for this pattern, why don't I just use shared_ptr ? etc., consider the point that I don't want to have undefined owner semantics. Although shared_ptr would have caught this particular case, it sends the wrong message to users of the system. It says, "I don't know who owns this, it could be you!"
What would have helped me would have been a weak pointer to a scoped pointer. In effect, a scoped pointer that has a list of weak references, that are nulled out when the scoped pointer destructs. This would allow single ownership semantics, but give the using objects a chance to catch the issue I ran into.
So at the expense of an extra 'weak_refs' pointer for the scoped_ptr and an extra pointer for the 'next_weak_ptr' in the weak_ptr, it would make a neat little single owner, multiple user structure.
It could maybe even just be a debug feature, so in 'release' the whole system just turns back into a normally sized scoped_ptr and a standard single pointer for the weak reference.
So..... my QUESTIONS after all of this are:
Is there such a pointer/patten already in stl/boost that I'm
missing, or should I just roll my own?
Is there a better way, that
still meets my single ownership goal?
Cheers,
Shane
2. Is there a better way, that still meets my single ownership goal?
Do use a shared_ptr, but as a class member so that it's part of the invariant of that class and the public interface only exposes a way to obtain a weak_ptr.
Of course, pathological code can then retain their own shared_ptr from that weak_ptr for as long as they want. I don't recommend trying to protect against Machiavelli here, only against Murphy (using Sutter's words). On the other hand, if your use case is asynchronous, then the fact that locking a weak_ptr returns a shared_ptr may be a feature!
Although shared_ptr would have caught this particular case, it sends the wrong message to users of the system. It says, "I don't know who owns this, it could be you!"
A shared_ptr doesn't mean "I don't know who owns this". It means "We own this." Just because one entity does not have exclusive ownership does not mean that anyone can own it.
The purpose of a shared_ptr is to ensure that the pointer cannot be destroyed until everyone who shares it is in agreement that it ought to be destroyed.
Is there such a pointer/patten already in stl/boost that I'm missing, or should I just roll my own?
You could use a shared_ptr exactly the same way you use a scoped_ptr. Just because it can be shared doesn't mean you have to share it. That would be the easiest way to work; just make single-ownership a convention rather than an API-established rule.
However, if you need a pointer that is single-owner and yet has weak pointers, there isn't one in Boost.
I'm not sure that weak pointers would help that much. Typically, if a
component X uses another component Y, X must be informed of Y's demise,
not just to nullify the pointer, but perhaps to remove it from a list,
or to change its mode of operation so that it no longer needs the
object. Many years ago, when I first started C++, there was a flurry of
activity trying to find a good generic solution. (The problem was
called relationship management back then.) As far as I know, no good
generic solution was every found; at least, every project I've worked on
has used a hand built solution based on the Observer pattern.
I did have a ManagedPtr on my site, when it was still up, which behaved
about like what you describe. In practice, except for the particular
case which led to it, I never found a real use for it, because
notification was always needed. It's not hard to implement, however;
the managed object derives from a ManagedObject class, and gets all of
the pointers (ManagedPtr, and not raw pointers) it hands out from it.
The pointer itself is registered with the ManagedObject class, and the
destructor of the ManagedObject class visits them all, and "disconnects"
them by setting the actual pointer to null. And of course, ManagedPtr
has an isValid function so that the client code can test before
dereferencing. This works well (regardless of how the object is
managed—most of my entity objects "own" themselves, and do a
delete this is response to some specific input), except that you tend
to leak invalid ManagedPtr (e.g. whenever the client keeps the pointer
in a container of some sort, because it may have more than one), and
clients still aren't notified if they need to take some action when your
object dies.
If you happen to be using QT, QPointer is basically a weak pointer to a QObject. It connects itself to the "I just got destroyed" event in the pointed-to value, and invalidates itself automatically as needed. That's a seriously hefty library to pull in for what amounts to bug tracking, though, if you aren't already jumping through QT's hoops.
Observer *o = New Observer();
Subject *s = new Subject() ;
s->register(o);
//Is it a good practice to delete the observer in the unregister function?
//I feel it is not. As the Observer object might still be in use, for example ,
//it might be registered to another Subject.
s->unregister(o);
//So it is safe to rely on the client code to delete the object or rely on the smart pointer things
delete o;
I want to confirm whether my above understanding is correct regarding who should delete the observer object.
I agree with your observation. It is not a good practice to delete the observer in the unregister function - for the simple fact that "one who creates the resource must be responsible for deleting the resource"
This will avoid
Magic behavior as perceived by the creator.
Code behavior will be well defined - one who creates must delete. Which will lay overall foundation of understanding of development for new developers to your system.
Similar topic are discussed under lengths in all books with different nomenclature.
I would say use smart pointers as no need to remember to call the delete explictly.
From a design point of view it should be superfluous (while not wrong) to unregister the subjects, if the observer is well implemented. Relying on external code for a behaviour to be robust if it can be enforced can always be considered as poor design.
Regarding the use of smart pointers, if you need the control on the destruction point for some reason (close files at a given point in time for example to avoid access problems in later code) then you should delete explicitly, otherwise it is far more comfortable to rely on smart pointers. That is why there are existing.
As the Subject did not allocate the Observer, it should not attempt to deallocate it. This allows the client of Subject to manage the lifetime and allocation strategy of Observers in any way it chooses (custom allocator, statically allocated, automatic variable). It doesn't force the client to use new.
Obviously it is still to clients responsibility not to allow the Observer to be destroyed before it is "unregistered".
E.g.
Observer o;
Subject s;
s.register(&o); // could take a reference
// ...
s.unregister(&o);
// No potential for forgotten deletes
It depends on your design. I personally prefer that deleting the Observer will automatically disassociate it with the subject, i.e deregister itself in the destructor. That saves the need to bother to deregister, which would require you to have references to both the Subject and the Observer at the point of destruction.
Smartpointer or client code (do not transfer ownership if possible)
If client code has created the object let the same code to destroy it :)
Another argument against deleting is what the Subject object communicates.
By deleting the object your Subject object has taken ownership of the object, as it controls its lifetime. As a raw pointer is passed into the object, and not an auto_ptr or an unique_ptr I would assume as a user of Subject that it does not take ownership of the object without looking at the code. So I would say that the interface of Subject does not communicate that it takes ownership of the object. So Subject should not delete it, because someone else (probably) has ownership of it.
In general, you should avoid side effects like deleting the pointer to an object in a container, unless the container is responsible for creating the pointer as well.
The problems of pointers with the Observer pattern runs a bit deeper than this as well.
An Observer inherently has a reference of some kind to the Subject. If that reference is a direct reference (e.g. not a handle), then if that object goes out of scope or gets deleted, when the Observer makes a Notify(...) call, it will throw an exception (or worse). So you must ensure you Detach(...) from the observer when you delete the Subject.
Forgetting to do this is a problem, so I like the idea of building it into the base class of the virtual destructor. This also means that the Subject has knowledge of the Observer (a reference to it) so it can call Detach(...). Which puts you into a similar situation with the Observer (i.e. if it gets deleted). The approach I have found simplest to use is to have the Observer actually be a singleton with Subjects registering for particular notifications, not just "I have some state for you to update". This is consistent with the GoF Page 298, item 7, "Specifying modifications of interest explicitly". Also, just plain makes sense to narrow the field on updates a bit. It also allows hooking up any Subject form anywhere easier.
Another case to consider is when the Subject is deleted during your Notify(..) iteration. In your Observer, you have a list of Subjects, A, B, and C. You change state and call Notify(...) on A. A deletes B. Now you move on to call Notify(...) on B, which does not exist. If you had it Detach(...) in the destructor, B may not be on the list any more. But it might still if you chose to iterate over a copy of the Subjects you started with instead of the actual list (been there, done that). Your Observer needs to handle a Detach(...) call during iteration for a Notify(...) for this reason.
I have a worked out example of this posted on a blog here.
I have an object which implements reference counting mechanism. If the number of references to it becomes zero, the object is deleted.
I found that my object is never deleted, even when I am done with it. This is leading to memory overuse. All I have is the number of references to the object and I want to know the places which reference it so that I can write appropriate cleanup code.
Is there some way to accomplish this without having to grep in the source files? (That would be very cumbersome.)
A huge part of getting reference counting (refcounting) done correctly in C++ is to use Resource Allocation Is Initialization so it's much harder to accidentally leak references. However, this doesn't solve everything with refcounts.
That said, you can implement a debug feature in your refcounting which tracks what is holding references. You can then analyze this information when necessary, and remove it from release builds. (Use a configuration macro similar in purpose to how DEBUG macros are used.)
Exactly how you should implement it is going to depend on all your requirements, but there are two main ways to do this (with a brief overview of differences):
store the information on the referenced object itself
accessible from your debugger
easier to implement
output to a special trace file every time a reference is acquired or released
still available after the program exits (even abnormally)
possible to use while the program is running, without running in your debugger
can be used even in special release builds and sent back to you for analysis
The basic problem, of knowing what is referencing a given object, is hard to solve in general, and will require some work. Compare: can you tell me every person and business that knows your postal address or phone number?
One known weakness of reference counting is that it does not work when there are cyclic references, i.e. (in the simplest case) when one object has a reference to another object which in turn has a reference to the former object. This sounds like a non-issue, but in data structures such as binary trees with back-references to parent nodes, there you are.
If you don't explicitly provide for a list of "reverse" references in the referenced (un-freed) object, I don't see a way to figure out who is referencing it.
In the following suggestions, I assume that you don't want to modify your source, or if so, just a little.
You could of course walk the whole heap / freestore and search for the memory address of your un-freed object, but if its address turns up, it's not guaranteed to actually be a memory address reference; it could just as well be any random floating point number, of anything else. However, if the found value lies inside a block a memory that your application allocated for an object, chances improve a little that it's indeed a pointer to another object.
One possible improvement over this approach would be to modify the memory allocator you use -- e.g. your global operator new -- so that it keeps a list of all allocated memory blocks and their sizes. (In a complete implementation of this, operator delete would have remove the list entry for the freed block of memory.) Now, at the end of your program, you have a clue where to search for the un-freed object's memory address, since you have a list of memory blocks that your program actually used.
The above suggestions don't sound very reliable to me, to be honest; but maybe defining a custom global operator new and operator delete that does some logging / tracing goes in the right direction to solve your problem.
I am assuming you have some class with say addRef() and release() member functions, and you call these when you need to increase and decrease the reference count on each instance, and that the instances that cause problems are on the heap and referred to with raw pointers. The simplest fix may be to replace all pointers to the controlled object with boost::shared_ptr. This is surprisingly easy to do and should enable you to dispense with your own reference counting - you can just make those functions I mentioned do nothing. The main change required in your code is in the signatures of functions that pass or return your pointers. Other places to change are in initializer lists (if you initialize pointers to null) and if()-statements (if you compare pointers with null). The compiler will find all such places after you change the declarations of the pointers.
If you do not want to use the shared_ptr - maybe you want to keep the reference count intrinsic to the class - you can craft your own simple smart pointer just to deal with your class. Then use it to control the lifetime of your class objects. So for example, instead of pointer assignment being done with raw pointers and you "manually" calling addRef(), you just do an assignment of your smart pointer class which includes the addRef() automatically.
I don't think it's possible to do something without code change. With code change you can for example remember the pointers of the objects which increase reference count, and then see what pointer is left and examine it in the debugger. If possible - store more verbose information, such as object name.
I have created one for my needs. You can compare your code with this one and see what's missing. It's not perfect but it should work in most of the cases.
http://sites.google.com/site/grayasm/autopointer
when I use it I do:
util::autopointer<A> aptr=new A();
I never do it like this:
A* ptr = new A();
util::autopointer<A> aptr = ptr;
and later to start fulling around with ptr; That's not allowed.
Further I am using only aptr to refer to this object.
If I am wrong I have now the chance to get corrections. :) See ya!