Why Handles Beat Pointers for Memory Safety in C and C++
Handles are the better pointers (2018)
After 15+ years wrestling with large C++ codebases, the author advocates replacing raw and smart pointers with index-handles. The approach centralizes memory management into systems, groups items into arrays, and hands out indices instead of pointers. This prevents memory corruption, reduces fragmentation, and improves cache performance. While not suited to classical OOP, it works well with data-oriented architectures and can even benefit garbage-collected languages by reducing GC pressure.
The worst case being tens- to hundreds-of-thousands of small C++ objects, each in its own heap allocation, pointing to each other through smart pointers.
- boricj
That's basically what I've done at work on my embedded project.
Object pools, with indices and generations. Way, way easier than meddling with raw pointers, cheaper than shared_ptr/weak_ptr and no clean-up required when deleting stuff because the stored generation won't match the new object's generation. You can even make that default-constructible if you increment the generation on instantiation too (so that only even generations are alive) and hide it all behind high-level abstractions with C++.
Though my knowledge of these techniques come from 2000s video game architectures, as games like GTA: Vice City are known to use it.
- nickwanninger
My PhD thesis is on this topic, and I had an ASPLOS paper on handle based memory support in unmanaged languages (C/C++) through LLVM a few years ago: https://nickw.io/papers/asplos24-alaska.pdf
The overhead we saw there is suprisingly just from instruction and branch overhead from using software handles - I have ongoing work to do it in hardware and the overheads are much lower.
- Conscat
I made a real attempt to program this way in my C++ project (largely due to this article), and personally I found it extremely cumbersome because you have to carry the owner of this resource everywhere you want to use the handle. That itself can worsen the performance when it's in different functions, it made generic programming hard and such code has to be more template heavy, and it was difficult to refactor.
But this was a very low level project, and I suspect Floooh was probably thinking more of end-user applications.