Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Returning 'c_str' from a function

This is from a small library that I found online:

const char* GetHandStateBrief(const PostFlopState* state)
{
    static std::ostringstream out;

    // ... rest of the function ...

    return out.str().c_str()
}

In my code I am doing this:

const char *d = GetHandStateBrief(&post);
std::cout<< d << std::endl;

Now, at first d contained garbage. I then realized that the C string I am getting from the function is destroyed when the function returns because std::ostringstream is allocated on the stack. So I added:

return strdup( out.str().c_str());

And now I can get the text I need from the function.

I have two questions:

  1. Am I understanding this correctly?

  2. I later noticed that out (of type std::ostringstream) was allocated with static storage. Doesn't that mean that the object is supposed to stay in memory until the program terminates? And if so, then why can't the string be accessed?

like image 849
user199421 Avatar asked Apr 17 '10 04:04

user199421


2 Answers

strdup allocates a copy of the string on the heap, which you have to free manually later (with free() I think). If you have the option, it would be much better to return std::string.

The static storage of out doesn't help, because .str() returns a temporary std::string, which is destroyed when the function exits.

like image 180
Marcelo Cantos Avatar answered Sep 20 '22 15:09

Marcelo Cantos


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.

like image 31
Matthew Flaschen Avatar answered Sep 17 '22 15:09

Matthew Flaschen