Today I tried to learn how to make a simple garbage collector for a future project, it didn't need to be fast nor complex nor optimal, it just needed to work. After lots of searching and reading, I was able to make something work.So, how can I improve it from here? At some point I guess I'll have to ditch the std::array (the small size is just for testing purposes). Do I actually need to use new and delete, or can I just keep using STL containers?For what I've read, I have a couple options: mark and compact, copying garbage collection, generational garbage collector. Which of them would be the more natural evolution from what I've done?#include <array>#include <iostream>#include <string>using std::cout;using std::endl;template <typename T>struct Handle {    bool marked {};    T value {};    Handle * next {};};template <typename T>class Heap {    std::array<Handle<T>, 10> heap;    Handle<T> * root {};    Handle<T> * free_list {};    void push(Handle<T> * handle) {        handle->next = free_list;        free_list = handle;    }    void reset() {        for (size_t i = 0; i < heap.size(); ++i) {            heap[i].marked = false;        }    }    void mark(Handle<T> * handle) {        if (handle && !handle->marked) {            handle->marked = true;            mark(handle->next);        }    }    void sweep() {        free_list = nullptr;        for (size_t i = 0; i < heap.size(); ++i) {            if (!heap[i].marked) {                heap[i].value = {};                push(&heap[i]);            }        }    }public:    Heap() {        for (size_t i = 0; i < heap.size(); ++i) {            push(&heap[i]);        }    }    template <typename U>    Handle<T> * allocate(U && u) {        if (!free_list) {            reset();            mark(root);            sweep();            if (!free_list) {                throw std::bad_alloc();            }        }        Handle<T> * handle = free_list;        free_list = free_list->next;        handle->value = std::forward<T>(u);        handle->next = nullptr;        return handle;    }    Handle<T> * keep_alive(Handle<T> * handle) {        handle->next = root;        root = handle;        return handle;    }    void signal() {        root = nullptr;    }};int main() {    Heap<std::string> heap;    auto a = heap.allocate(A);    auto b = heap.keep_alive(a);    a = heap.allocate(B);    auto c = heap.keep_alive(a);    a = heap.allocate(C);    a = heap.allocate(D);    a = heap.allocate(E);    cout << a->value << endl;    cout << b->value << endl;    cout << c->value << endl;    return 0;}
First garbage collector
c++;memory management