-1

Consider the MWE below,

std::string return_string() 
{
    return "this is a string"
}
int main()
{
    const char *y = return_string().c_str();
    std::string str = return_string();
    const char *x = str.c_str();

    std::cout << return_string() << std::endl; //Prints "this is a string"
    std::cout << y << std::endl;  // Prints Weird characters
    std::cout << x << std::endl;  //Prints "this is a string"

    std::cin.ignore();
    return 0;
}

I have a function which returns a string and I need to convert it to a c-style string. Doing return_string().c_str() gives me weird output like ▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌p. But if I store the output of a function in a string first and then convert that string to a c-style string it works. What is wrong with the first way?

void life
  • 172
  • 3
  • 11
  • The string returned in `return_string` is a temporary. A pointer (like `char*`) will not preserve the lifetime of that temporary. – AndyG May 18 '17 at 19:07
  • 3
    As an aside, it appears today is a slow day. Everyone is racing to write their own answer to a question that has been asked a dozen times. – AndyG May 18 '17 at 19:11
  • How is that a MWE? It doesn't even compile. – Lightness Races in Orbit May 18 '17 at 19:11
  • Really it compiles for me on visual studio. Sorry about the duplicate, it's hard to search for answers without the familiarity of the terms used. – void life May 18 '17 at 19:20
  • 2
    @voidlife: No worries on your part. The answerers know better. Duplicates: [1](http://stackoverflow.com/q/27627413) [2](http://stackoverflow.com/q/35980664) [3](http://stackoverflow.com/q/19244331) [4](http://stackoverflow.com/q/6456359) [5](http://stackoverflow.com/q/2657178) [6](http://stackoverflow.com/q/10006891) [7](http://stackoverflow.com/q/15449544) [8](http://stackoverflow.com/q/22330250) [9](http://stackoverflow.com/q/3733582) [10](http://stackoverflow.com/q/24488122) [11](http://stackoverflow.com/q/33659609) [12](http://stackoverflow.com/q/35993690) There's more, too – AndyG May 18 '17 at 19:26
  • 2
    Duplicates round two: [13](http://stackoverflow.com/q/23464504) [14](http://stackoverflow.com/q/41240590) [15](http://stackoverflow.com/q/11368483) [16](http://stackoverflow.com/q/14820008) [17](http://stackoverflow.com/q/40553758) [18](http://stackoverflow.com/q/14748860) [19](http://stackoverflow.com/q/20883180) [20](http://stackoverflow.com/q/12323049) [21](http://stackoverflow.com/q/14533540) [22](http://stackoverflow.com/q/23016688) [23](http://stackoverflow.com/q/23869552) [24](http://stackoverflow.com/q/25380253) – AndyG May 18 '17 at 19:34
  • 2
    Duplicates round three [25](http://stackoverflow.com/q/26304239) [26](http://stackoverflow.com/q/18044605) [27](http://stackoverflow.com/q/31690826) [28](http://stackoverflow.com/q/39006506) [29](http://stackoverflow.com/q/2833682) [30](http://stackoverflow.com/q/34873395) [31](http://stackoverflow.com/q/35425068) [32](http://stackoverflow.com/q/4564540) [33](http://stackoverflow.com/q/5947129) [34](http://stackoverflow.com/q/27256277) [35](http://stackoverflow.com/q/25658553) [36](http://stackoverflow.com/q/13474486) [37](http://stackoverflow.com/q/4804154) – AndyG May 18 '17 at 19:43

3 Answers3

3

When you do return_string().c_str() you get the pointer to a temporary object that will go out of scope once the expression is finished. If you save the pointer and use it later you will have undefined behavior.

With

std::string str = return_string();

you copy the returned temporary object. Getting a pointer to the copy will work since it still exists in the program at the point when you use the pointer.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
1
const char *y = return_string().c_str();

is a problem if you wish to use y later to access the contents. In that line, the return value of return_string() is a temporary that gets destroyed after that line is executed. Hence, y is dangling pointer.

Accessing the contents of a dangling pointer causes undefined behavior.

When you use

std::string str = return_string();
const char *x = str.c_str();

x is not a dangling pointer as long as str is in scope. Hence,

std::cout << x << std::endl;

is well behaved.

R Sahu
  • 204,454
  • 14
  • 159
  • 270
0

You can't "convert from string to const char*". No such thing exists, because a const char* does not contain characters. It is not a string! It only pointers to some characters somewhere.

In this case, via std::string::c_str(), it points to characters that no longer exist.

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055