Boost logo

Boost :

From: Chelly (postmast.root.admi.gov_at_[hidden])
Date: 1999-07-23 22:39:50


At 01:43 PM -0500 1999.07.23, Andy Glew wrote:
>>At 03:55 PM 7/22/99 -0700, Reid Sweatman wrote:
>>>Anyway, I support your notion of a requested/in progress page for
>>>the site.
>
>I hope that nobody minds if I submit the following request?
>Maybe one of you can point be to existing code; or maybe
>I will be shamed enough to write it.
>
>Today's request: live_ptr
>
>live_ptr<T>
>
> A live_ptr is a variety of smart pointer that does not deallocate
> the object pointed to as long as there is a reference, etc. I.e.
> it is not a garbage collecting or reference counting pointer.
>
> Instead, a live_ptr points to the object as long as the object lives;
> when the object pointed to dies (is destroyed), then the live_ptr
> is set to 0.
[snip]
> Alternate names: valid_ptr
>
> I have encountered several different implementations of live_ptr,
> with slightly different semantics and intrusiveness. live_ptrs
> are usually derived from registered_ptrs. Because of the limitations
> of C++, it is usuall necessary to have the pointed to data type
> itself be derived from live_ptee, although, if you can add a hook
> to all destructors, you can avoid this annoyance.
>
> Typically, the live_ptee destructor walks a registry which points
>to the
> live_pts themselves (not the objects they are embedded in).
>
> Methods: all pointer methods, registering on copying, assignment, etc.

You know, this is funny, because I was working on a whole family of this
exact thing a few days ago. The watched object must exist before the
watcher pointer(s) is made to it. After that, they can be destroyed in any
order. If the watched object is destroyed before the pointer(s), the
pointer(s) becomes aware of this fact. I also realized this is a specific
case of a more general event generator/receiver pattern where the generator
or receivers can be destroyed in any order, without ill effects.

As you say, the basic design is to have the object being watched know about
the watcher(s) (or some central registry). In the single watcher case, the
watched object has a back pointer to the watcher pointer (if there is one).
In the multiple case, one approach I used was to link everything in a
circular linked list (double or single - it was a template parameter which
to use). All of these were very low overhead (at most a three pointer
overhead).

A while back I wrote a manager that had a central registry as you describe.
It used an interesting scheme to find if the object still existed, in an
efficient way. Essentially once a record of an object was allocated in the
registry, it was never deleted (until the registry was destroyed). Each
record had a pointer to the object being monitored and a version number.
When a monitored object was destroyed, the version number was incremented
in the record. Pointers to the monitored object were implemented as a
pointer to the record in the registry, and a current version number.
Getting a pointer to the actual monitored object was a single compare of
the versions, and if they matched, getting the pointer to the monitored
object from the record.

[snip]

>versioned_ptr<type T, version_offset VO, pointer_registry R = 0 >
>
> A versioned pointer is another pointer class on which a live_ptr
>may be based.
>
> Rather than explicitly going and finding the pointers pointing to
>an object when
> an object is deallocated, versioned_ptrs keep a version number
>with the pointer.
>
> For a versioned pointer to be valid, it's version number must
>match the version
> number placed in the object, which may be specified at template
>use point.
> (If, that is, you are one of the lucky people whose C++ compiler
>supports
> pointer to member as a template parameter.)
>
> When the object is deallocated, it's version number is changed.
>
> Versioned pointers are a little bit less safe than explicitly
>zeroed live_ptrs,

I'd say "unsafe".

> since there is always a remote chance that the memory of the
>object may be
> reallocated, and exactly the same bitpattern may be reused for the
>version.

A little chance is too much for a quality system.

> You can only eliminate this possibility by assuming full control
>over new
> and delete.

I'm not so sure about this. You'd have to really put some control over them.

> On the other hand, versioned pointers are often faster than live_ptrs,
> since deallocation does not require any backpoiner list traversal.
>
> Myself, I would never voluntarily use versioned pointers - I don't
>like
> things that probably won't crash. Unfortunately, I have to work with
> a large open source program that uses them a lot (the SimpleScalar
>simulator),
> albeit in ways that I think make it safe.

This isn't conforming - accessing memory once it's been deleted. I
definitely wouldn't use this at all - it simply isn't robust.

------------------------------------------------------------------------

eGroups.com home: http://www.egroups.com/group/boost
http://www.egroups.com - Simplifying group communications


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk