Will this leak memory?

Even if you never forget to call free() in every possible branch of your calling code, it's impolite towards your users to impose the burden of cleaning up your memory onto the caller.

If you use a container like String or an owning pointer like std::unique_ptr, you simply don't have to worry about that, the compiler will always clean it up for you, in all possible scenarios, early returns, exceptions, etc. This lowers the cognitive load and allows you to focus on the actual logic and structure of the program rather than memory management.

All of that is of course ignoring the problematic aspects of using dynamic allocation on a microcontroller.