If you need something more powerful, Boost.Interprocess is also a thing[1]. I used it like 10 years ago and seemed to work well. Looking at the docs, it even has a RAII-ish thing called `boost::interprocess::remove_shared_memory_on_destroy`.
[1] https://www.boost.org/doc/libs/1_85_0/doc/html/interprocess....
Briefly: my implementation uses a templated RAII-style wrapper that persists objects in shared memory for as long as an instance of that object remains in scope. Once the last object goes out of scope, shared memory is freed. It works great so far. I’ll probably reference this library to compare implementations and see what I can learn. Thanks again.