Weird behavior while converting a std::string to a

2019-08-27 22:45发布

I was playing with some strings when I stumbled upon a weird behavior while converting a std::string to a LPCSTR.

I have written a small test application to demonstrate :

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

using namespace std;

int main ()
{
    string stringTest = (string("some text") + " in addition with this other text").c_str(); 
    LPCSTR lpstrTest= stringTest.c_str();
    cout << lpcstrTest << '\n';

    cout << (string("some text") + " in addition with this other text").c_str() << '\n';

    LPCSTR otherLPCSTR= (string("some text") + " in addition with this other text").c_str();
    cout << otherLPSTR;
}

And here is the output :

some text in addition with this other text
some text in addition with this other text
îþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþ...[more unreadable stuff]...

I am simply wondering what is causing this strange behavior.

Thank you

3条回答
劳资没心,怎么记你
2楼-- · 2019-08-27 23:22

The pointer returned by c_str() is only valid as long as its string object is.

// A copy of a temporary string is made here. The temporary is destructed 
// but stringTest stays in scope until the end of main
string stringTest = (string("some text") + " in addition with this other text").c_str();

LPCSTR lpstrTest= stringTest.c_str();
cout << lpcstrTest << '\n';

// the temporary is in scope until the end of the full expression, so this is fine.

cout << (string("some text") + " in addition with this other text").c_str() << '\n';

// But this isn't. At the end of the line, the temporary string object is long gone.
// otherLPCSTR now points to deallocated memory.
LPCSTR otherLPCSTR= (string("some text") + " in addition with this other text").c_str();

// And here you're accessing that memory.
cout << otherLPSTR;
查看更多
走好不送
3楼-- · 2019-08-27 23:23

Temporary object created by an expression lives until the evaluation of the full expression is complete. Once the full expression is evaluated, all its temporaries are automatically destroyed.

This is what happens to

LPCSTR otherLPCSTR = 
  (string("some text") + " in addition with this other text").c_str();

Immediately after this statement the temporary is destroyed, and otherLPCSTR ends up pointing into dead memory.

In the first case the stringTest is not a temporary. It lives to the end of main, meaning that lpstrTest pointer remains valid.

In the second case the temporary std::string object is used for output immediately while it is still alive.

Only in the third case you are attempting to store a pointer, which gets invalidated as described above.

查看更多
Fickle 薄情
4楼-- · 2019-08-27 23:37
LPCSTR otherLPCSTR= (string("some text") + " in addition with this other text").c_str();
cout << otherLPSTR;

The part

 (string("some text") + " in addition with this other text")

creates a so-called "temporary" object, which has no name and gets destructed when the statement that contains it finishes. You get the c_str() from that, which points to some internal storage of that temporary object. You assign that c_str() to the otherLPCSTR variable. After that, "the statment that contains the temporary string" has finished, so the temporary string gets destructed, and the otherLPCSTR points "nowhere".

查看更多
登录 后发表回答