And this compose function could easily be written in C to take the "addr" as an argument to be filled, rather than provide it as a return value. Then it can be entirely stack allocated. The caller would need to make sure that the "addr" array was large enough of course.
I started learning C and C++ together at the same time a few years ago. I prefer to code in C++, using the standard template library, but there's always this extremely annoying little voice in the back of my head saying, "you could do this more efficiently if you operated on character arrays instead of a std::string"