C++ MFC отсутствует const char* переменная
Итак, у меня есть этот простой код внутри метода нажатия кнопки:
std::stringstream ss;
unsigned counter = 0;
while(true)
{
ss.clear();
ss << DEFAULT_USER_CONFIG_NAME << " " << ++counter;
const char* name = ss.str().c_str();
MessageBox(name);
/* ... while break condition */
}
Проблема в том, что ящик сообщений пуст. Но это работает правильно, когда я передаю текст напрямую:
MessageBox(ss.str().c_str()); // that shows text just fine
Что я нашел с отладчиком, так это то, что локальная переменная "имя" не создается (по крайней мере, она не отображается в отладчике). Любая подсказка, почему это работает, когда передается напрямую и не работает в противном случае? Также, когда я произвел "name" в CString, он вернул true при проверке IsEmpty().
1 ответ
Выражение ss.str()
создает временный std::string
объект. Сохранение результата c_str()
таким образом указывает на временную память, которая быстро превращается в висячий указатель. После полного выражения заявления
const char* name = ss.str().c_str();
// ^ this is where the temporary ss.str() gets destroyed.
оценивается, временный уничтожается.
Вы уже знаете, как решить эту проблему, поместив выражение, создающее временное выражение, в полное выражение, которое его использует. Это продлевает время жизни временного до конца полного выражения:
MessageBox(ss.str().c_str());
// ^ this is where the temporary ss.str() gets destroyed.
Следующее иллюстрирует последовательность событий. Давайте просто определим несколько заполнителей классов и функций:
void messagebox(const char*) {
cout << "messagebox()" << endl;
}
struct tmp {
tmp(const char* content) : content(content) { cout << "tmp c'tor" << endl; }
~tmp() { cout << "tmp d'tor" << endl; }
const char* c_str() { return content.c_str(); }
private:
string content;
};
struct ss {
tmp str() { return tmp("test"); }
};
С этим на месте, ваша первая версия
ss s;
const char* name = s.str().c_str();
messagebox(name);
производит следующий вывод:
tmp c'tor tmp d'tor messagebox()
Тогда как вторая версия
ss s;
messagebox(s.str().c_str());
изменяет последовательность в выводе:
tmp c'tor messagebox() tmp d'tor