11

Is the following safe as is, without an explicit cast or call to std::string constructor? If not safe, why not?

std:string myfunc()
{
    char buf[128] = "";
    // put something into buf or not base on logic.

   return buf;
}
1
  • actually the title of the question is incorrect. You're returning char array as std::string. Commented Mar 16, 2011 at 16:47

4 Answers 4

9

Yes. That is perfectly fine. The caller will get a copy of the local buffer, because std::string would make a deep-copy out of this local buffer!

EDIT: I'm assuming the buf is null-terminated string!

Sign up to request clarification or add additional context in comments.

3 Comments

Not safe unless buf is definitely null terminated!
@T33C: Correct. I added this underlying assumption!
It is bad programming practice to assume things. Rather one should ensure that the return is going to be safe. The code in the question does not ensure this if buf is later modified as the comment suggests.
4

Yes that is fine, remember in C++, what will happen is an implicit constructor will be called to create the return object, and a string can be constructed with a character array. In C++ you have to explicitly return by reference if you don't want a copy created.

2 Comments

Not safe unless buf is definitely null terminated!
it is safe, as described by @karlphillip below, because the statement char buf[128] = ""; is an initialization that will set buf to point to a null terminated empty string, it is not setting a single character in the array.
3

Actually, it is safe. But that's just because you are initializing the char array like that, which is extremely important. Consider the following code:

#include <string.h>
#include <iostream>
#include <string>

std::string alloc_string(bool fill)
{
    char buf[128] = ""; // Proper declaration/initialization of the array. 

    if (fill)
    {
        strcpy(buf, "qwerty");
    }

    return buf;
}

int main()
{
    std::string empty_str = alloc_string(false);
    std::cout << "empty_str size is: " << empty_str.size() << std::endl;

    std::string str = alloc_string(true);
    std::cout << "str size is: " << str.size() << std::endl;
    std::cout << "str: " << str << std::endl;
}

Outputs:

empty_str size is: 0
str size is: 6
str: qwerty

1 Comment

If you forget to initialize the array you'll certainly break the code as there could be garbage on that block of memory. Try that and you'll probably notice that empty_str is not empty anymore, even though you didn't copied anything to it.
0

safe (for null terminated buffer) but not easy to read, consider to change the last line to

return std::string(buf);

Edit: please see the karlphillip on safety.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.