Because you obtain memory, and don't give it back. malloc gets you memory -- to give it back you need free. I probably should have put that in my function but I wasn't sure it would actually work.
Your first one is perhaps the more insidious, since "return buffer" makes you think that you are lobbing that memory back to the person who called you (which makes it their problem to free it, not yours). However, since you are returning a std::string, that's not true -- the string is constructed from that buffer and the string is returned -- the buffer is no longer needed. In order to deal with this, you should explicitly construct a string object, then free the memory, then return the new string object (don't worry, it has it's own copy of the data, so you giving the original copy away won't hurt).