MyTetra Share
Делитесь знаниями!
Классическая ошибка в работе со строками на стыке Qt и Си
Время создания: 23.11.2023 11:48
Текстовые метки: язык, C, C++, Си, Си++, Qt, строка, функция, c_str, ошибка, память, выделение, указатель, стык, кракозябры, временный, объект
Раздел: Компьютер - Программирование - Язык C++ (Си++) - Библиотека Qt - Принципы написания кода
Запись: xintrea/mytetra_syncro/master/base/1700729282ez59z4guaz/text.html на raw.github.com

Вопрос


Пишу такой код:


QString logFileName="/Directory/Logs/Log.txt";

qDebug() << "Log file name: " << logFileName;


const char *fileName = logFileName.toStdString().c_str();

printf("Const char * filename: ");

printf(fileName);

printf("\n");



И на экране получаю кракозябры вместо правильного значения строки fileName:


Log file name: "/Directory/Logs/Log.txt"

Const char * filename: X���[



Я давно с сишными низкоуровневыми делами не работал. Почему кракозябры вместо строки?



Ответ


Проблема в выражении:



const char *fileName = logFileName.toStdString().c_str();



Когда срабатывает метод toStdString(), создается временный объект типа std::string как возвращаемое значение данного метода. Потом для этого временного объекта вызывается c_str(). Полученный указатель запоминается в fileName, но затем временный объект удаляется (ведь работа выражения завершена, объект std::string ничему не присвоен а значит и не нужен), и начинается выполнение следующей команды.


Таким образом, указатель fileName начинает указывать на память, которая когда-то была выделена объекту, но затем уже в следующих командах реаллоцирована под другие данные.


Другими словами, кратко: память была выделена объекту, который перестает существовать после выполнения данной строки кода. А указатель fileName продолжает указывать на эту память.


Так же в этом разделе:
 
MyTetra Share v.0.65
Яндекс индекс цитирования