Char* pointer returned by QString::toAscii().constdata() seems to be corrupted when QTextStream object is created
-
Hi,
I am working on an application where I need to pass a const char* to a library function. Since I am using QString objects in my code, I used the QString::toAscii().constdata() function to pass the data pointed by QString. This seem to work in general. However, when I added a qDebug() statement in the code after the toAscii() call, the data seems to get corrupted. To test this out, I created a small test program as listed below:
@
#include <QTextStream>
#include <iostream>int main(int argc, char *argv[])
{
QString testStr("Hello");QTextStream out(stdout);
//========================================================
// Tried with the following options and none of the options
// work.
// toUtf8()
// toAscii()
// toLocal8Bit()
// toLatin1()
//=======================================================
const char* dataPtr = testStr.toLatin1().constData();int i = 0;
//=====================================================================
// This part of the code does works fine, ie the output is as expected.
//=====================================================================
while( dataPtr[i] != '\0' )
{
printf
(
"%s %d: dataPtr[d]=%c(d) Addr:%p Addr[%d]:%p\n",
FILE, LINE, i,
dataPtr[i], dataPtr[i], dataPtr, i, &dataPtr[i]
);
i++;
}
std::cout << FILE << " " << LINE << " Length of str: " << i << std::endl;//==============================================================
// Problem: commenting this line seems to fix the data corruption
// for the data pointed by dataPtr
//==============================================================
QTextStream out2(stdout);i = 0;
//=====================================================================
// This part of the code does not work, ie the content of the dataPtr is
// corrupted, if the QTextStream object is created above.
// If the QTextStream is not created then the output is ss expected.
//=====================================================================
while( dataPtr[i] != '\0' )
{
printf
(
"%s %d: dataPtr[d]=%c(d) Addr:%p Addr[%d]:%p\n",
FILE, LINE, i,
dataPtr[i], dataPtr[i], dataPtr, i, &dataPtr[i]
);
i++;
}
std::cout << FILE << " " << LINE << " Length of str: " << i << std::endl;return 0;
}
@The output of the code after creating "out2" object is not correct.
This is the output I get:
@main.cpp 31: dataPtr[00]=H(0072) Addr:0x9a8c38 Addr[0]:0x9a8c38
main.cpp 31: dataPtr[01]=e(0101) Addr:0x9a8c38 Addr[1]:0x9a8c39
main.cpp 31: dataPtr[02]=l(0108) Addr:0x9a8c38 Addr[2]:0x9a8c3a
main.cpp 31: dataPtr[03]=l(0108) Addr:0x9a8c38 Addr[3]:0x9a8c3b
main.cpp 31: dataPtr[04]=o(0111) Addr:0x9a8c38 Addr[4]:0x9a8c3c
main.cpp 36 Length of str: 5
main.cpp 56: dataPtr[00]=�(-032) Addr:0x9a8c38 Addr[0]:0x9a8c38
main.cpp 56: dataPtr[01]=�(-099) Addr:0x9a8c38 Addr[1]:0x9a8c39
main.cpp 56: dataPtr[02]=�(-082) Addr:0x9a8c38 Addr[2]:0x9a8c3a
main.cpp 56: dataPtr[03]=q(0113) Addr:0x9a8c38 Addr[3]:0x9a8c3b
main.cpp 56: dataPtr[04]=�(-117) Addr:0x9a8c38 Addr[4]:0x9a8c3c
main.cpp 56: dataPtr[05]=(0127) Addr:0x9a8c38 Addr[5]:0x9a8c3d
main.cpp 61 Length of str: 6@
Here are the details of the Qt and platform:OS: Linux, Ubuntu 10.04
Qt: Qt version: 4.7.3
make: GNU Make 3.81Can you let me know what is done incorrectly here? All I want is a copy of the data pointed by QString, if there an alternative way please let me know.
Thanks in advance
Rama. -
Try to store the returned "QString::toLatin1":http://developer.qt.nokia.com/doc/qt-4.8/qstring.html#toLatin1, after
@
const char* dataPtr = testStr.toLatin1().constData();
@
no longer exists.
Try something like :
@
QByteArray latinArray = testStr.toLatin1();
const char* dataPtr = latinArray.constData();
@ -
toLatin1() creates a temporary QByteArray object, constData() returns a pointer to it's data array. As soon as you hit the semicolon, the temporary byte array is destructed and the const char pointer is invalid and does not point to valid data anymore. Some or all of the bits and bytes can remain in memory unchanged, this is why your first loop seems to work. In fact, this is by pure chance! Move the QTextStream out(stdout) after your toLatin1() line and you have corrupted data in the first loop too!
The trick is to make the byte array permanant by assigning it to a variable of its own, like cincirin suggested.
BTW: your printf format string does not match the argument list, you miss some %.