Boost logo

Boost :

From: Corey Goldfeder (goldfeder_at_[hidden])
Date: 2008-07-03 02:10:44


Hi everyone,

Would there be any interest in a mixin class that signs an object as being
on the stack or the heap? Any class that needs to know if it can delete
'this' can (possibly multiply) inherit from class HeapAware, and will gain a
member function on_heap() that returns whether the object was dynamically
allocated.

A similar idea is discussed in More Effective C++, item 27, but unlike that
approach, my implementation works correctly for arrays. It also does all the
work during construction, so that checking on_heap() just returns a preset
bool. The extra cost at construction is a small constant. It is not yet
thread safe, but could be made so reasonably easily. Unlike some similar
classes, it uses nothing compiler specific, even for arrays, which is where
people usually need to "cheat". In particular, for arrays it makes no
assumptions about where in the allocated memory the objects are constructed,
and so alignment issues or extra compiler bookkeeping don't cause any
problems.

I currently use this class within a 3d mesh library I maintain. I have
triangles that belong to multiple meshes, and I want updates to a triangle
to be noticed by all meshes that contain it, so that they can mark their
cached mesh statistics as being out of date. This means I need an event
listener mechanism. I also want triangles ownership to be shared among the
meshes, so that deleting a mesh deletes any triangles that no other mesh
currently contains. I built a two way smart pointer / event listener class
that maintains a single list that serves as both listeners and owners. The
HeapAware class that I am proposing for Boost was invaluable to me, because
it allowed me to disable self deletion for triangles on the stack.

The snippet below demonstrates how HeapAware can be used. (Obviously this a
trivial example). My implementation produces the correct output for all
these cases, as well as for globals, statics, and objects created with
placement new and placement new[]. It also works correctly with copy
construction, which some other implementations fail at.

class Widget : public HeapAware {};

int main() {
  Widget stack_w;
  Widget* heap_w = new Widget;
  Widget stack_copy(*heap_w);
  Widget* heap_copy = new Widget(stack_w);
  Widget stack_array_w[2];
  Widget* heap_array_w = new Widget[2];

  printf("Stack Widget: %d\n", stack_w.on_heap());
  printf("Heap Widget: %d\n", heap_w->on_heap());
  printf("Stack copy of Heap widget: %d\n", stack_copy.on_heap());
  printf("Heap copy of Stack widget: %d\n", heap_copy->on_heap());
  printf("Stack array widget 0: %d\n", stack_array_w[0].on_heap());
  printf("Stack array widget 1: %d\n", stack_array_w[1].on_heap());
  printf("Heap array widget 0: %d\n", heap_array_w[0].on_heap());
  printf("Heap array widget 1: %d\n", heap_array_w[1].on_heap());

  return 0;
}

Thanks!
-Corey Goldfeder


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