Extracting const char* from QStringList
-
I start off with a QString:
QString appName = QApplication::applicationName();
After the assignment appName contains "MillikanUI", I've verified this in the debugger. I then split this into a QStringList:
QStringList appNameList = appName.split("U");
appNameList now contains 2 elements:
[0] "Millikan" [1] "I"
I then try to convert the first element to a const char*:
const char* baseName = qPrintable(appNameList.at(APP_NAME_BASE));
APP_NAME_BASE is an enumerated type with the value 0. I'm using qPrintable because I tried toLatin1() and it returned the same sort of random characters that I'm now seeing returned by qPrintable. I've also tried appNameList[APP_NAME_BASE] with the same random results.
After the assignment baseName points to what looks like completely random content, nothing like the content of the element at 0 in the QStringList. What is going on?
-
I start off with a QString:
QString appName = QApplication::applicationName();
After the assignment appName contains "MillikanUI", I've verified this in the debugger. I then split this into a QStringList:
QStringList appNameList = appName.split("U");
appNameList now contains 2 elements:
[0] "Millikan" [1] "I"
I then try to convert the first element to a const char*:
const char* baseName = qPrintable(appNameList.at(APP_NAME_BASE));
APP_NAME_BASE is an enumerated type with the value 0. I'm using qPrintable because I tried toLatin1() and it returned the same sort of random characters that I'm now seeing returned by qPrintable. I've also tried appNameList[APP_NAME_BASE] with the same random results.
After the assignment baseName points to what looks like completely random content, nothing like the content of the element at 0 in the QStringList. What is going on?
@SPlatten
the trick is to not use a temporary QByteArray, when you try to access its internal const char* array :Dint main(int argc, char *argv[]) { QApplication app(argc, argv); app.setApplicationName("MillikanUI"); QString appName = QApplication::applicationName(); QStringList appNameList = appName.split("U"); //Non Temporary QByteArray QByteArray nonTemporayByteArray = appNameList.first().toLatin1(); const char *data = nonTemporayByteArray.constData(); qDebug() << data; //Temporary QByteArray data = appNameList.first().toLatin1().constData(); qDebug() << data; return app.exec(); }
-
I start off with a QString:
QString appName = QApplication::applicationName();
After the assignment appName contains "MillikanUI", I've verified this in the debugger. I then split this into a QStringList:
QStringList appNameList = appName.split("U");
appNameList now contains 2 elements:
[0] "Millikan" [1] "I"
I then try to convert the first element to a const char*:
const char* baseName = qPrintable(appNameList.at(APP_NAME_BASE));
APP_NAME_BASE is an enumerated type with the value 0. I'm using qPrintable because I tried toLatin1() and it returned the same sort of random characters that I'm now seeing returned by qPrintable. I've also tried appNameList[APP_NAME_BASE] with the same random results.
After the assignment baseName points to what looks like completely random content, nothing like the content of the element at 0 in the QStringList. What is going on?
@SPlatten said in Extracting const char* from QStringList:
After the assignment baseName points to what looks like completely random content, nothing like the content of the element at 0 in the QStringList. What is going on?
What's going on is described in the
qPrintable()
documentation https://doc.qt.io/qt-5/qtglobal.html#qPrintable : The char pointer will be invalid after the statement in whichqPrintable()
is used. This is because the array returned byQString::toLocal8Bit()
will fall out of scope.A
const char *
variable stores a single pointer. It does not store a string. You must ensure the memory that stores your pointed data remains valid for the lifetime of the pointer. -
@SPlatten said in Extracting const char* from QStringList:
After the assignment baseName points to what looks like completely random content, nothing like the content of the element at 0 in the QStringList. What is going on?
What's going on is described in the
qPrintable()
documentation https://doc.qt.io/qt-5/qtglobal.html#qPrintable : The char pointer will be invalid after the statement in whichqPrintable()
is used. This is because the array returned byQString::toLocal8Bit()
will fall out of scope.A
const char *
variable stores a single pointer. It does not store a string. You must ensure the memory that stores your pointed data remains valid for the lifetime of the pointer.@JKSH , I also tried:
const char* baseName = ((appNameList[APP_NAME_BASE]).toLatin1()).data();
That didn't work either, what does work is:
QString appName(appNameList[APP_NAME_BASE]); QByteArray appNameBA = appName.toLatin1(); const char* baseName = appNameBA.constData();
-
@JKSH , I also tried:
const char* baseName = ((appNameList[APP_NAME_BASE]).toLatin1()).data();
That didn't work either, what does work is:
QString appName(appNameList[APP_NAME_BASE]); QByteArray appNameBA = appName.toLatin1(); const char* baseName = appNameBA.constData();
@SPlatten said in Extracting const char* from QStringList:
That didn't work either
That's because you triggered the same phenomenon in both cases: A dangling pointer.
This is an important concept in C/C++. Take some time to ensure you intimately understand how dangling pointers come about; this will spare you lots headaches in the future.
-
@JKSH , I also tried:
const char* baseName = ((appNameList[APP_NAME_BASE]).toLatin1()).data();
That didn't work either, what does work is:
QString appName(appNameList[APP_NAME_BASE]); QByteArray appNameBA = appName.toLatin1(); const char* baseName = appNameBA.constData();
@SPlatten said in Extracting const char* from QStringList:
const char* baseName = ((appNameList[APP_NAME_BASE]).toLatin1()).data();
This can not work!
appNameList[APP_NAME_BASE]).toLatin1()
will create a new QByteArray instance, which will be directly destroyed after the call.
SobaseName
becomes a dangling pointer.If you want this to work, you must ensure object instance will not be destroyed as long as you are working with it.
const auto buffer = appNameList[APP_NAME_BASE].toLatin1(); const char* baseName = buffer.constData();
baseName
will be valid as longs asbuffer
is not destroyed.