2016-09-12 26 views
1

Так что я, что простой код внутри метода щелчка кнопки:C++ MFC отсутствует Const символ * переменная

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 пуста. Но она работает правильно, когда я прохожу текст непосредственно:

MessageBox(ss.str().c_str()); // that shows text just fine 

То, что я нашел с отладчиком, что «название» локальная переменная не создается (по крайней мере, он не отображается в отладчике). Любая подсказка, почему она работает, когда передается напрямую и не работает иначе? Кроме того, когда я выбрал «имя» для CString, он вернул true при проверке IsEmpty().

+1

Все это в соответствии со стандартом. Проблема с первой версией заключается в том, что 'ss.str()' разрушается до 'MessageBox (name)' call. У вас есть какие-либо вопросы? – LogicStuff

ответ

5

Выражение 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 

(Live sample code)

+0

Благодарим вас за ответ. Любые идеи, почему отладчик вообще не показывает переменное «имя»? [Visual Studio 2010] – Arrekin

+0

@ Аррекин: в первом фрагменте кода 'имя' должно отображаться как на вкладках * Местные жители *, так и на * Авто *. Если он не показывает, я не знаю, почему. В сборке отладки он должен указывать на строку с содержимым «0xCD», отмечая освобожденную память. Если вам нужно проверить переменные, которые не отображаются автоматически, вы всегда можете добавить [смотреть] (https://msdn.microsoft.com/en-us/library/0taedcee.aspx). – IInspectable