For solution to circular references, see here :-).
For solution to circular references, see here. :-).
I've looked at the problem a dozen different ways over the years, and the only solution I've found that works every time is to re-architect my solution to not use a circular reference. Edit: Can you expand? For example, how would you deal with a parent-child relation when the child needs to know about/access the parent?
€“ OB OB As I said, the only good solution is to avoid such constructs unless you are using a runtime that can deal with them safely. That said, if you must have a tree / parent-child data structure where the child knows about the parent, you're going to have to implement your own, manually called teardown sequence (i.e. External to any destructors you might implement) that starts at the root (or at the branch you want to prune) and does a depth-first search of the tree to remove references from the leaves.It gets complex and cumbersome, so IMO the only solution is to avoid it entirely.
1 same here. For a sample approach see my answer on another question: stackoverflow. Com/questions/1047877/… – Fredrik Mörk Jul 1 '09 at 14:15 1 Can you expand?
For example, how would you deal with a parent-child relation when the child needs to know about/access the parent? – OB OB Jul 1 '09 at 14:18 @ChrisW: Weak references were mentioned in the original question. OB OB was looking for alternatives.
– Randolpho Jul 1 '09 at 15:22.
Here is a solution I've seen: Add a method to each object to tell it to release its references to the other objects, say call it Teardown(). Then you have to know who 'owns' each object, and the owner of an object must call Teardown() on it when they're done with it. If there is a circular reference, say A B, and C owns A, then when C's Teardown() is called, it calls A's Teardown, which calls Teardown on B, B then releases its reference to A, A then releases its reference to B (destroying B), and then C releases its reference to A (destroying A).
I think that in most cases, you'd like to call teardown from within the object's destructor. Calling teardown explicitly is somewhat similiar to destroying the object manually. (How do you know that nobody else is using the object when tearing it down?) – OB OB Jul 1 '09 at 14:30 Yes, you're right, call Teardown in the object's destructor.
However, calling Teardown doesn't necessarily destroy the object, if someone else has a reference to it then it will stay alive. Objects only get destroyed when reference counts reach 0. – Alex Black Jul 1 '09 at 14:46 Let me correct that: Calling Teardown on an object does not necessarily destroy it, but it means the object is not longer useful, its similar to calling Dispose().
Since the object has released its references to the objects it depends on, its not safe to use. – Alex Black Jul 1 '09 at 15:22 @Alex Black: What if there are 2 objects C and D who own A. Then when C calls Teardown(), but D still wants it alive?
You have to have a counter in object A that will ignore all Teardown calls except last one. – alpav Dec 1 '09 at 16:33 @alpav: What we did was avoided that scenario. Only one of C or D could own A.
Say C owns A and D does not, but D has a reference to A, then you have to design your code in such a way that D doesn't access A after C is gone, one way to do that is make D owned by C. – Alex Black Dec 1 '09 at 17:22.
I guess another method, used by garbage collectors, is "mark and sweep": Set a flag in every object instance Traverse the graph of every instance that's reachable, clearing that flag Every remaining instance which still has the flag set is unreachable, even if some of those instances have circular references to each other.
As I said, I am not asking for alternatives to refernce counting, but for solutions to circular references. – OB OB Jul 1 '09 at 14:32 What's the "problem" with circular references that you're trying to solve: is it the problem of garbage collection, or a different problem? If the problem is garbage collection, isn't an alternative the same thing as a solution?
– ChrisW Jul 1 '09 at 14:36 @ChrisW: Yes, the problem is generally garbage collection. There are many methods for garbage collections. One of them is reference counting, another one is mark-and-sweep.
Mark-and-sweep is an example of an alternative to reference counting as a gc method, weak-references are an example to a solution to circular references while still using reference counting as the gc method, on the other hand. I hope you see the difference. – OB OB Jul 1 '09 at 14:40 If you want to do it using only first-class references, then you need a way to detect circularity.
Alex Black's method should do that: pretend to deference everything that a referenced object is pointing to, and if that experiment results in the original object's being dereferenced then it's a circular reference. I don't know but maybe that's an expensive way to do it: more expensive than mark and sweep, especially in pathological / long-chain cases. – ChrisW Jul 1 '09 at 14:56 1 You could actually use a garbage collector in tandem with reference counting.
The reference count causes stuff to be cleaned up immediately if possible, and the GC handles the circular references (and if MOST things are automatically deleted via the reference count, the GC has less work to do! ) – Grant Peters Jul 1 '097 at 8:22.
I'd like to suggest a slightly different method that occured to me, I don't know if it has any official name: Objects by themeselves don't have a reference counter. Instead, groups of one or more objects have a single reference counter for the entire group, which defines the lifetime of all the objects in the group. In a similiar fashion, references share groups with objects, or belong to a null group.
A reference to an object affects the reference count of the (object's) group only if it's (the reference) external to the group. If two objects form a circular reference, they should be made a part of the same group. If two groups create a circular reference, they should be united into a single group.
Bigger groups allow more reference-freedom, but objects of the group have more potential of staying alive while not needed.
That's equivalent to stating which of your references are 'weak': if a reference is to an object in the same group then the reference is 'weak', else it's to an object in a different group and so that reference is 'strong'. – ChrisW Jul 1 '09 at 15:23 1 Yeah, only that if you have an external reference to object A that holds the weak reference to object B, and B is not otherwise referenced, B would still stay alive (which is the wanted behavior). You don't get that with "ordinary" weak references.
– OB OB Jul 1 '09 at 15:46 Sounds similar to having discreet memory pools for different parts of the application (so you can just delete an entire pool at once and then its just cleaning up pointers into the pool), which is commonly used in games, and adding a reference count (which I guess would solve the problem of cleaning up pointers) – Grant Peters Jul 21 '09 at 8:20.
I have always redesigned to avoid the issue. One of the common cases where this comes up is the parent child relationship where the child needs to know about the parent. There are 2 solutions to this Convert the parent to a service, the parent then does not know about the children and the parent dies when there are no more children or the main program drops the parent reference.
If the parent must have access to the children, then have a register method on the parent which accepts a pointer that is not reference counted, such as an object pointer, and a corresponding unregister method. The child will need to call the register and unregister method. When the parent needs to access a child then it type casts the object pointer to the reference counted interface.
There are couple of ways I know of for walking around this: The first (and preferred one) is simply extracting the common code into third assembly, and make both references use that one The second one is adding the reference as "File reference" (dll) instead of "Project reference" Hope this helps.
The question is not about references between assmeblies, but references between objects (from the tags, in a reference-counting, ie non-garbage-collecting, environment) – AakashM Jul 1 '09 at 14:29.
I cant really gove you an answer,but what I can give you is a way to a solution, that is you have to find the anglde that you relate to or peaks your interest. A good paper is one that people get drawn into because it reaches them ln some way.As for me WW11 to me, I think of the holocaust and the effect it had on the survivors, their families and those who stood by and did nothing until it was too late.