Copying GC が何なのか, という事については authorNari さんの記述や pasberth さんの記述に任せるとして, ここでは満たすべき機能を記述したいと思います.
(1) プログラマの記述した型に適合した heap から allocate してくる.
// int に適合した heap を適当に 256 用意する.
memory_manager<int> manager(256);
// ここで allocate する.
int *x = manager.alloc(10);(2) GC が有効なメモリ領域かそうでないかを判断できるように, root を設定する.
// alloc した x にある領域を root として設定する.
manager.set_root(x);(3) root, 或いは root から辿れる参照にあるメモリ領域から, 別のメモリ領域を接続する. ただし manager が (1) のタイミングで自動で root からの被参照として登録する事はない.その様な実装も場合によっては有効かもしれないが, 各々の依存性がないため, 最早それは GC の必要なデータ構造ではない.
int *y = manager.alloc(1), *z = manager.alloc(2);
// x -> y -> z -> x
manager.join(x, y);
manager.join(y, z);
manager.join(z, x);(4) 孤立したメモリ領域を自動的に検出して破棄する.
// int[5] の孤立した空間を alloc してみる.
manager.alloc(5);
// プログラマの決めたタイミングで gc を走らせる.
// manager.alloc(5) した空間が消えている.
manager.run();
// x -/-> y -> z -> x の場合,
// z が x に依存していても, x から最終的に z までの依存が切れているので
// y, z は消える.
manager.disjoin(x, y);
manager.run();