This is from a small library that I found online:
const char* GetHandStateBrief(const PostFlopState* state)
{
static std::ostringstream out;
// ...
You're right that out is a static variable allocated on the data segment. But out.str() is a temporary allocated on the stack. So when you do return out.str().c_str() you're returning a pointer to a stack temporary's internal data. Note that even if a string is not a stack variable, c_str is "only granted to remain unchanged until the next call to a non-constant member function of the string object."
I think you've hit on a reasonable workaround, assuming you can't just return a string.