Clearly this is for Wouter to reply regarding C++.
But if you use the FlatCC C api that is designed for detailed control over memory, the finalize call returns a copy of the buffer either to user allocated memory, or to a dynamically allocated buffer depending on the exact call. If dynamically allocated, the memory must be explicitly released with either free, or flatcc_builder_aligned_free, again depending on the exact call.
The internal memory used for buffer construction is a circular buffer of pages, and some small stacks. This memory will be reused after a release call. After release it is no longer possible to call finalize, but whatever you retrieved from an earlier buffer is now yours, and the internal memory can be reused immediately. The release call has a variant where you can decide if the internal memory should be reduced in size in case there were a large peak.
If more control is needed it is possible to customize the emitter to use a different structure than paged memory - it is like a write interface. Your application can consume those data directly as it is immitted (but the buffer will not be valid to read before it is all pieced together in linear memory). You can also customize the allocator used for the internal stacks by using a custom init call to the builder - this is also used with a customized emitter.