LINUX.ORG.RU

странное поведение std::string::c_str()

 , std string


0

2

второй день сижу туплю, не могу понять, в чем дело. Жил был код:

const char * pcDN = rxBaseObject.toString().c_str();
и в один прекрасный день на одной прекрасной строке (точнее группе строк) стал вести себя интересным образом. После его выполнения в pcDN образуется валидный указатель на пустую строку. В то время как все предыдущие и последующие вызовы rxBaseObject.toString().c_str(); возвращают нормальный указатель на нужный массив.

тестовый кусок полностью

TRACE("rxBaseObject: " << rxBaseObject.toString()); //работает
TRACE("rxBaseObject cstr: " << rxBaseObject.toString().c_str()); //работает
const char * pcDN = rxBaseObject.toString().c_str();
TRACE("pcDN: " << pcDN); // пустая строка
char temp[256];
strcpy(temp, rxBaseObject.toString().c_str());
TRACE("temp: ", temp); // работает
pcDN = rxBaseObject.toString().c_str();
TRACE("pcDN: " << pcDN); // пустая строка

не работает именно случай, когда возвращаемое значение кладется в переменную. Как такое может быть? Ткните плз носом, что за фигня?

Так а toString случайно не живет только на время вызова? c_str гарантированно остается правильным только на время жизни объекта-строки.

note173 ★★★★★
()

если toString имеет прототип std::string toString() , то соответственно эта временная строка разрушается в конце выражения.

Vinick ★★
()
Ответ на: комментарий от Vinick

слона-то я и не заметил. спасибо, в следующий раз буду внимательнее. Но тогда вопрос, почему указатель остается валидным и указывает на нулевую строку? хотя это наверно стоит в сорцах STL глянуть

marvin_yorke ★★★
() автор топика
Ответ на: комментарий от marvin_yorke

что значит валидным? он указывает куда-то в кучу где когда-то что-то лежало. Кому сейчас принадлежит этот кусок памяти неизвестно. А то что там оказывается пустая строка, то это может просто повезло, а может быть действительно STL затирает.

Vinick ★★
()
Ответ на: комментарий от Vinick

во всех остальных случаях не затирал же. хотя смотрю на еще один баг в трекере, который падал в том же самом месте, и там сегфолт, т.е. судя по всему иногда указатель таки становился невалидным. Надо действительно глянуть в исходники std::string для верности

marvin_yorke ★★★
() автор топика

Жил был

через дефис, но это пофиг...

slackwarrior ★★★★★
()
Ответ на: комментарий от marvin_yorke

Да, а на нулевую строку указывать может, например, из-за сборки в debug режиме.

Лучше использовать std::string везде, раз уж все равно есть stl. А в const char переводить только для вывода.

note173 ★★★★★
()
Ответ на: комментарий от note173

там для вывода и используется. точнее для перекодирования в BER для отправки на LDAP-сервер

marvin_yorke ★★★
() автор топика

Ты знал что c_str() аллочит новый кусок памяти и возвращает его тебе)

Boy_from_Jungle ★★★★
()

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

Вы берете у временного объекта c_str, и затем используете этот указатель после смерти временного объекта.

gzh
()
Ответ на: комментарий от gzh

Я не в танке )) почему-то ответы не показывались )

gzh
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.