Newsgroups: alt.lang.design,comp.lang.c,comp.lang.c++,comp.lang.lisp
Path: cantaloupe.srv.cs.cmu.edu!das-news2.harvard.edu!news2.near.net!howland.reston.ans.net!news.sprintlink.net!EU.net!uunet!allegra!alice!ark
From: ark@research.att.com (Andrew Koenig)
Subject: Re: Reference Counting (was Re: Searching Method for Incremental Garbage Collection)
Message-ID: <CzqDJn.6xq@research.att.com>
Organization: Software Engineering Research Department
References: <1994Nov21.181455.13457@isis.muc.de> <CzoE9n.3oM@research.att.com> <3atajl$6sh@gateway.wiltel.com>
Date: Wed, 23 Nov 1994 17:21:22 GMT
Lines: 57
Xref: glinda.oz.cs.cmu.edu comp.lang.c:117628 comp.lang.c++:100091 comp.lang.lisp:15781

In article <3atajl$6sh@gateway.wiltel.com> igor_chudov@wiltel.com (Igor Chudov) writes:
> Andrew Koenig (ark@research.att.com) wrote:
> : In article <1994Nov21.181455.13457@isis.muc.de> Mike.Chapman@muc.de (Mike Chapman) writes:

> : > Almost any non trivial structure in the real world, 
> : > if you are actually going to do anything with it,
> : > needs back pointers (simple example - doubly linked lists) 
> : > or pointers to parents (simple example - almost any tree structure)
> : > or whatever.

> : Sure, but such pointers do not prevent reference counting from working.

> Can you give us a clue how you can make reference counting working with
> circular references. Could you also give us some kind of estimate about 
> efficiency. How many operations will this algorithm do each time some pointer
> changes? 

Sure, no problem.

As a limiting case, doubly linked lists, cited above as a `circular
data structure,' don't require use counts at all -- at least not in
the linked items.

A fairly typical C++ approach to such a problem (noting that I did
respond to this article in comp.lang.c++) is along the following lines:

One class represents a node in the list.  It contains a pair of pointers,
forward and back, and whatever other data is contained in a node.  That
class is not available to users in general; it is part of the implementation.

A second class represents the entire list.  It contains a pair of
pointers to the head and tail of the list and also a use count.
That count holds the number of instances of...

A third class, which represents a user's view into the list.
Such a class is often called an iterator, for people not reading
this in comp.lang.c++.  Operations on the third class will
typically include following the links forward and backward,
fetching (a copy of) the information in a node, changing that
information, and so on.

Objects of this third class are defined in a way that keeps
the use count current in the second class.  Whenever one of
these objects comes into existence, its constructor increments
the use count of the list structure to which it refers.  When
one of these objects disappears, its destructor decrements the
use count; when it reaches zero, the entire list is deleted.

The point of all this is that because the actual data structure
is concealed from its users, it is possible to ensure that the
pointers are always well-behaved.  It is therefore unnecessary to
put use counts in the data structure itself.  Moreover, use count
fiddling is not generally necessary when using the data structure;
only when creating and deleting user-accessable "pointers" into it.
-- 
				--Andrew Koenig
				  ark@research.att.com
