c++ how to make sure memory is reclaimed via shared pointers - c++

I am using boost shared pointers and these pointers are really shared all over the application. There are conditions, where such a shared pointer becomes invalid. For example, a shared pointer to a network resource, that can become invalid because network became unavailable. In such a scenario, where the shared pointer becomes invalid, i would like all objects to stop using it. How can i send a message to all objects that the pointer is invalid. If it was a normal pointer, i could set it to null and all client code should be checking for null pointer before using it. But, in case of a shared pointer, which keeps reference count, how can i achieve similar functionality ?

You can use weak pointers. That is, the code that handles the network events has the shared_ptr<Res> while everybody else has a weak_ptr<Res>. Now,
when the resource becomes unavailable, just reset the shared_ptr to NULL;
when a client wants to use the resource, call lock() into the weak_ptr and test whether the returned shared_ptr is valid before using.

If it was a normal pointer, i could set it to null and all client code should be checking for null pointer before using it.
I doubt that. You'd then have copies of that raw pointer that point to invalid objects. You'd think that would solve the problem, but it doesn't. It amplifies it.
The fact is that the shared pointer itself doesn't become invalid, the object it contains does. So, logically, whether it's still safe to use it should be contained in the object, not the shared pointer.
a shared pointer to a network resource, that can become invalid because network became unavailable.
Just throw an exception when you attempt to call a method that attempts to use the network...

I would be inclined to follow the pattern used by standard streams: have an object that represents the resource, which can enter an error state and/or throw an exception when it detects (or is informed) that the network is no longer available. If you can't change the existing resource class, then this new object can hold the existing resource object (that currently all your users have shared pointers to), and the users can share the new object.
Unless you need all the users of this resource to respond promptly when it becomes unavailable, there doesn't seem any point trying to propagate a message to them all. If you just want them to stop using it, they can do that the next time they try to use it, and discover that it doesn't work any more. If they do really need a message, then write something to keep a list of them all, and call some function on them when the event that they're interested in occurs. This is called the Observer pattern or "listeners", and armed with those search terms you can find implementations and alternatives.
Ideally, users should be able to check for the error state either as part of using the resource, or immediately afterwards. Testing before use is usually error-prone, since it creates a window in which the network perhaps could become unavailable after the test but before it's used. Once your code has to handle that case correctly you might as well make it the only case, by not bothering to check in advance.

You need to store more information. You could put the resource together with a bool in a tuple, or you could use boost::optional, and set it to none when you want to invalidate it.

You almost certainly shouldn't be using shared pointer for this, since
its semantics don't correspond to what you need. Shared pointer
implements a sort of poor man's garbage collection, where the object
ceases to exist when there are no more pointers to it; you need the
opposite, that the pointers to the object cease to exist when there is
no more object. (A reverse garbage collection, so to speak.)
I've used a ManagedPtr in the past; the pointer registers itself with
the object, which must derive from a ManagingObj class which sets the
pointers to null in its destructor. This works sometimes, but it still
doesn't remove entries from lists, etc. where the other objects may be
keeping it. And in practice, other objects which know about your
network resource object may want to take specific actions when it
disappears. In the end, you almost always need to use the observer
pattern: any object which acquires a pointer to your object registers
with it to be notified in case of its demise.

Related

C++ Is making objects depend on others a good design?

I have a basic design that consists of three classes : A Data class, A Holder class wich holds and manages multiple Data objects, and a Wrapper returned by the Holder wich contains a reference to a Data object.
The problem is that Wrapper must not outlive Holder, or it will contain a dangling reference, as Holder is responsible for deleting the Data objects. But as Wrapper is intended to have a very short lifetime (get it in a function, make some computation on its data, and let it go out of scope), this should not be a problem, but i'm not sure this is a good design.
Here are some solutions i thought about:
-Rely on the user reading the documentation, technically the same thing happens with STL iterators
-Using shared_ptr to make sure the data lasts long enought, but it feels like overkill
-Make Wrapper verify its Holder still exists each time you use it
-Any idea?
(I hope everyone can understand this, as english is not my native language)
Edit : If you want to have a less theoric approach, this all comes from a little algorithm i'm trying to write to solve Sudokus, the Holder is the grid, the Data is the content of each box (either a result or a temporary supposition), and the Wrapper is a Box class wich contains a reference to the Data, plus additional information like row and column.
I did not originally said it because i want to know what to do in a more general situation.
Only ever returning a Wrapper by value will help ensure the caller doesn't hold onto it beyond the calling scope. In conjunction with a comment or documentation that "Wrappers are only valid for the lifetime of the Holder that created them" should be enough.
Either that or you decide that ownership of a Data is transferred to the Wrapper when the Wrapper is created, and the Data is destroyed along with the Wrapper - but what if you want a to destroy a Wrapper without deleting the Data? You'd need a method to optionally relinquish ownership of the Data back to the Holder.
Whichever you choose, you need to decide what owns (ie: is responsible for the lifetime of) Data and when - once you've done that you can, if you want, use smart pointers to help with that management - but they won't make the design decision for you, and you can't simply say "oh I'll use smart pointers instead of thinking about it".
Remember, if you can't manage heap memory without smart pointers - you've got no business managing heap memory with them either!
To elaborate on what you have already listed as options,
As you suggested, shared_ptr<Data> is a good option. Unless performance is an issue, you should use it.
Never hold a pointer to Data in Wrapper. Store a handle that can be used to get a pointer to the appropriate Data object. Before Data is accessed through Wrapper, get a pointer the Data object. If the pointer is not valid, throw an exception. If the pointer is valid, proceed along the happy path.

Ownership and how to avoid shared_ptr

I'm trying to write a simple event manager class and listeners for a game engine. In the usual implementation (i.e. McShaffry) the event manager registers listeners which in principle saves a shared_ptr to the listener as a private member.
I have seen in many instances people saying that shared_ptr and the likes should be avoided (eg here). Thus, I'm trying to find ways to implement the event manager without sharing ownership of the listeners.
One method I've thought of, is assigning unique ids to the listeners and register their ids with the event manager. Then the listeners are responsible of 'asking' the event manager after it has updated, if any events are available under their id.
I would like to ask if there are cleaner and/or standard methods to avoid shared ownership in this case, but also generally. For example, I have the same problem with the listeners. The listeners need to store a pointer to their parent (or the object for which they are listening) so that they can call its methods when handling an event.
As Mat’s comment says, there’s no reason not to use smart pointers in general. That said, the cautionary warning does seem to apply in your situation: as far as I understand you don’t have shared ownership; the event manager has sole ownership of the listeners. A shared_ptr would thus be inappropriate here.
An alternative would be to use a unique_ptr which is in many ways the other side of the shared_ptr coin. But depending on how you model listeners even that can be avoided by simply saving concrete instances to the event manager. Without a more detailed description it’s impossible to say whether you need pointers at all but if you don’t need them then, yes, the advice applies: don’t use (smart) pointers when concrete objects would do.
Finally, if your listeners are objects whose ownership is managed elsewhere consider simply using raw pointers to those objects: in that case, the event manager isn’t at all owner of the object – neither the sole nor a shared owner. While this would be the preferred way for me, it requires careful analysis about the listeners’ life-time to ensure that the event manager doesn’t point to listeners which don’t exist any more.
shared_ptr tends to be overused; it is often recommended, for example, on SO as a solution to vaguely stated pointer problems. It is not a substitute for good design, and should not be used unless there is a design in place that is based on understanding object lifetime issues in the code being written.
From personal experience, shared_ptrs a great, but sometimes may not be the correct tool for the job. If the code is entirely under your control, 99.9% of the time, shared_ptr will likely make your life easier. You do need to make sure you don't do thinks like:
Foo *f = new Foo();
shared_ptr<Foo> fptr(f);
shared_ptr<Foo> fptr2(f);
This will cause the memory for f to be deallocated with either fptr1 or fptr2. Instead you want to do something like:
Foo *f = new Foo();
shared_ptr<Foo> fptr(f);
shared_ptr<Foo> fptr2 = fptr;
In the second case, the assignment of one shared pointer to another will increment the reference count.
Another place where you can get in trouble with shared_ptr is if you need to pass a naked pointer to a function (this might occur if you need to pass this as the first parameter to a method, or you are relying on a 3rd party library). You can get the naked pointer from the shared_ptr, but you aren't guaranteed the memory address it's pointing to will still be around, as the reference counter won't be incremented.
You can around this by keeping an additional shared_ptr, though this can be a hassle.
There are other forms of smart pointers. For example, OpenSceneGraph has a ref_ptr which is easier to work with than shared_ptr. The one caveat, is that all objects it points to must descend from Referenced. However, if you're okay with that, I think it's a lot more difficult to have really bad things happen.
In some cases shared_ptr is overkill or doesn't properly exibhit the desired semantics (for example passing ownership).
What you need to do is look at your design and see what ownership model you need. If you need/want shared ownership then just use shared_ptr to model that. If a shared/ref counted ownership is not appropriate use another smart pointer.
Wouldn't your case be a good fit for a nice use of auto_ptr described here : http://www.gotw.ca/publications/using_auto_ptr_effectively.htm (guru of the week «using auto_ptr effectively)
For what I understand, you build a listener, then give it to an event manager. So the event manager can be seen as a "sink".
With the auto_ptr technique, your event manager can cleanly and safely take full ownership of the listener you give him.

C++ safe object deletion

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).

Weak reference to a scoped_ptr?

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.

How can I maintain a weak reference on a COM object in C++?

In my application, I'm hooking various functions for creating COM objects (such as CoCreateInstanceEx) to get notified whenever some object is created. I'm keeping track of all created objects in a std::list and I'm iterating over that list to do various things (like checking which OLE objects have been activated).
The issue with this is that right now, whenever adding an IUnknown pointer to my list, I call IUnknown::AddRef on it to make sure that it doesn't get destroyed while I'm tracking it. That's not what I really want though; the lifetime of the object should be as long (or short) as it is without my tracing code, so I'd rather like to maintain a weak reference on the objects. Whenever the last reference to some tracked COM object is removed (and thus the object gets destroyed), I'd like to get notified so that I can update my bookkeeping (e.g. by setting the pointer in my list to NULL).*
What's the best way to do this? Right now, I'm patching the (first) VTable of all created objects so that the calls to IUnknown::Release via the first vtable get notified. However, this won't work for COM interfaces which inherit from multiple interfaces (and thus have multiple vtables), but I'm not sure whether this is really a problem: given the Rules for Implementing QueryInterface, there should always be just one IUnknown returned by IUnknown::QueryInterface, right? So I could do that and then patch that vtable.
Furthermore, this approach is also a bit hairy since it involves creating thunks which generate some code. I only implemented this for 32bit so far. Not a big issue, but still.
I'm really wondering whether there isn't a more elegant way to have a weak reference to a COM object. Does anybody know?
*: The next thing I'll have to solve is making this work correctly in case I have active iterators (I'm using custom iterator objects) traversing the list of COM objects. I may need to keep track of the active iterators and once the last one finished, remove all null pointers from the list. Or something like that.
This isn't an answer as much as a set of issues why this is a really tricky thing to do - I'm putting it in as an answer since there's too much information here than fits in a comment :)
My understanding is that the concept of weak reference just doesn't exist in COM, period. You've got reference counting via IUnknown, and that's the sum total of how COM deals with object lifetime management. Anything beyond that is, strictly speaking, not COM.
(.Net does support the concept, but it's got an actual GC-based memory manager to provide appropriate support, and can treat WeakRef objects differently than regular references in memory. But that's not the case with the very simple world that COM assumes, which is a world of plain memory and pointers, and little more.)
COM specifies that reference counting is per-interface; any COM object is free to do ref counting per object as a convenience, but the upshot is that if you're wrapping an object, you have to assume the most restrictive case. So you cannot assume that any given IUnknown will be used for all addrefs/releases on that object: you'd really need to track each interface separately.
The canonical IUnknown - the one you get back by QI'ing for IUnknown - could be any interface at all - even a dedicated IUnknown that is used only for the purpose of acting as an identity! - so long as the same binary pointer value is returned each time. All other interfaces could be implemented any way; typically the same value is returned each time, but a COM object could legitimately return a new IFoo each time someone QI's for IFoo. Or even keep around a cache of IFoos and return one at random.
...and then you've got aggregation to deal with - basically, COM doesn't have a strong concept of object at all, it's all about interfaces. Objects, in COM, are just a collection of interfaces that happen to share the same canonical IUnknown: they might be implemented as a single C/C++ object behind the scenes, or as a family of related C/C++ objects presenting a facade of a 'single COM object'.
Having said all of that, given that:
I'm tracing the state of various components (including all COM objects) of this software for the sake of debugging
Here's an alternate approach that might produce some useful data to debug with.
The idea here is that many implementations of COM objects will return the ref count as the return value to Release() - so if they return 0, then that's a clue that the interface may have been released.
This is not guaranteed, however: as MSDN states:
The method returns the new reference count. This value is intended to be used only for test purposes.
(emphasis added.)
But that's apparently what you're doing here.
So one thing you could do, assuming you own the calling code, is to replace calls with Release() with an inline called MyRelease() or similar that will call release, and if it notices that the return value is 0, then notes that the interface pointer is now possibly freed - removes it from a table, logs it to a file, etc.
One major caveat: keep in mind that COM does not have a concept of weak ref, even if you try to hack something together. Using a COM interface pointer that has not been AddRef()'d is illegal as far as COM is concerned; so if you save away interface pointer values in any sort of list, the only thing you should so with those is treat them as opaque numbers for debugging purposes (eg. log them to a file so you can correlate creates with destroys, or keep track of how many you have outstanding), but do not attempt to use them as actual interface pointers.
Again, keep in mind that nothing requires a COM object to follow the convention of returning the refcount; so be aware that you could see something that looks like a bug but is actually just an implementation of Release just happens to always returns 0 (or rand(), if you're especially unlucky!)
First, you're right that QueryInterface for IUnknown should always return the same pointer; IUnknown is treated as the object's identity IIRC, so needs to be stable.
As for weak pointers, off the top of my head, maybe you could give CoMarshalInterThreadInterfaceInStream a whirl? It is meant to allow you to serialize a reference to a COM object into a stream, then create a new reference to the object on some other thread using the stream. However, if you serialise into a stream and retain the stream as a sort of weak pointer, then unmarshal later on to recover the pointer, you could check whether unmarshalling fails; If so, the object is gone.
With WinRT IWeakReference was added to enable weak refs to COM objects. Objects created with WRL's RuntimeClass support IWeakReference by default (can be disabled with an option).
you can use IWeakReference in your designs but it means you will need to use at least some WinRT concepts, IInspectable based interface.