Странное поведение при преобразовании std::string в LPCSTR

Я играл с некоторыми строками, когда наткнулся на странное поведение во время преобразования std::string к LPCSTR,

Я написал небольшое тестовое приложение, чтобы продемонстрировать:

#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;
}

И вот вывод:

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

Мне просто интересно, что вызывает это странное поведение.

Спасибо

3 ответа

Решение
LPCSTR otherLPCSTR= (string("some text") + " in addition with this other text").c_str();
cout << otherLPSTR;

Часть

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

создает так называемый "временный" объект, который не имеет имени и разрушается после завершения оператора, который его содержит. Вы получаете c_str() от этого, который указывает на некоторое внутреннее хранилище этого временного объекта. Вы присваиваете этот c_str() другой переменной LPCSTR. После этого "состояние, содержащее временную строку" завершено, поэтому временная строка уничтожается, а остальные LPCSTR указывают "никуда".

Временный объект, созданный выражением, живет до тех пор, пока оценка полного выражения не будет завершена. Как только полное выражение оценено, все его временные значения автоматически уничтожаются.

Это то, что происходит с

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

Сразу после этого заявления временный уничтожается, и otherLPCSTR заканчивает тем, что указывает на мертвую память.

В первом случае stringTest не временный. Доживает до конца main, означающий, что lpstrTest указатель остается в силе.

Во втором случае временный std::string Объект используется для вывода немедленно, пока он еще жив.

Только в третьем случае вы пытаетесь сохранить указатель, который становится недействительным, как описано выше.

Указатель возвращается c_str() допустимо только до тех пор, пока его строковый объект.

// 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;
Другие вопросы по тегам