December 28, 2011

rkintada rkintada
Lab Rat
8 posts

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:

  1. #include <QTextStream>
  2. #include <iostream>
  3.  
  4. int main(int argc, char *argv[])
  5. {
  6.    QString testStr("Hello");
  7.  
  8.    QTextStream out(stdout);
  9.  
  10.    //========================================================
  11.    // Tried with the following options and none of the options
  12.    // work.
  13.    // toUtf8()
  14.    // toAscii()
  15.    // toLocal8Bit()
  16.    // toLatin1()
  17.    //=======================================================
  18.    const char* dataPtr = testStr.toLatin1().constData();
  19.  
  20.    int i = 0;
  21.  
  22.    //=====================================================================
  23.    // This part of the code does works fine, ie the output is as expected.
  24.    //=====================================================================
  25.    while( dataPtr[i] != '\0' )
  26.    {
  27.       printf
  28.       (
  29.          "%s %d: dataPtr[d]=%c(d) Addr:%p Addr[%d]:%p\n",
  30.          __FILE__, __LINE__, i,
  31.          dataPtr[i], dataPtr[i], dataPtr, i, &dataPtr[i]
  32.       );
  33.       i++;
  34.    }
  35.    std::cout << __FILE__ << " " << __LINE__ << " Length of str: " << i << std::endl;
  36.  
  37.    //==============================================================
  38.    // Problem: commenting this line seems to fix the data corruption
  39.    // for the data pointed by dataPtr
  40.    //==============================================================
  41.    QTextStream out2(stdout);
  42.  
  43.    i = 0;
  44.  
  45.    //=====================================================================
  46.    // This part of the code does not work, ie the content of the dataPtr is
  47.    // corrupted, if the QTextStream object is created above.
  48.    // If the QTextStream is not created then the output is ss expected.
  49.    //=====================================================================
  50.    while( dataPtr[i] != '\0' )
  51.    {
  52.       printf
  53.       (
  54.          "%s %d: dataPtr[d]=%c(d) Addr:%p Addr[%d]:%p\n",
  55.          __FILE__, __LINE__, i,
  56.          dataPtr[i], dataPtr[i], dataPtr, i, &dataPtr[i]
  57.       );
  58.       i++;
  59.    }
  60.    std::cout << __FILE__ << " " << __LINE__ << " Length of str: " << i << std::endl;
  61.  
  62.    return 0;
  63. }

The output of the code after creating “out2” object is not correct.

This is the output I get:

  1. ================================================
  2. main.cpp 31: dataPtr[00]=H(0072) Addr:0x9a8c38 Addr[0]:0x9a8c38
  3. main.cpp 31: dataPtr[01]=e(0101) Addr:0x9a8c38 Addr[1]:0x9a8c39
  4. main.cpp 31: dataPtr[02]=l(0108) Addr:0x9a8c38 Addr[2]:0x9a8c3a
  5. main.cpp 31: dataPtr[03]=l(0108) Addr:0x9a8c38 Addr[3]:0x9a8c3b
  6. main.cpp 31: dataPtr[04]=o(0111) Addr:0x9a8c38 Addr[4]:0x9a8c3c
  7. main.cpp 36 Length of str: 5
  8. main.cpp 56: dataPtr[00]=(-032) Addr:0x9a8c38 Addr[0]:0x9a8c38
  9. main.cpp 56: dataPtr[01]=(-099) Addr:0x9a8c38 Addr[1]:0x9a8c39
  10. main.cpp 56: dataPtr[02]=(-082) Addr:0x9a8c38 Addr[2]:0x9a8c3a
  11. main.cpp 56: dataPtr[03]=q(0113) Addr:0x9a8c38 Addr[3]:0x9a8c3b
  12. main.cpp 56: dataPtr[04]=(-117) Addr:0x9a8c38 Addr[4]:0x9a8c3c
  13. main.cpp 56: dataPtr[05]=(0127) Addr:0x9a8c38 Addr[5]:0x9a8c3d
  14. main.cpp 61 Length of str: 6
  15. ===============================================

Here are the details of the Qt and platform:

OS: Linux, Ubuntu 10.04
Qt: Qt version: 4.7.3
make: GNU Make 3.81

Can 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.

5 replies

December 28, 2011

cincirin cincirin
Ant Farmer
387 posts

Try to store the returned QString::toLatin1 [developer.qt.nokia.com], after

  1. const char* dataPtr = testStr.toLatin1().constData();

no longer exists.
Try something like :
  1. QByteArray latinArray = testStr.toLatin1();
  2. const char* dataPtr = latinArray.constData();

December 28, 2011

Andre Andre
Area 51 Engineer
6031 posts

This is a FAQ. Seriously: there are notes in the docs about this, and a section in the FAQ on this site dedicated to it. Please search first, then ask.

 Signature 

Looking for Qt developers to join our team @ i-Optics: https://qt-project.org/forums/viewthread/25393/

December 28, 2011

Volker Volker
Robot Herder
5428 posts

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 %.

December 28, 2011

rkintada rkintada
Lab Rat
8 posts

Cool. Thanks to cincirin and Andre for the reply. The code now works fine. The explanation makes sense. Regarding the missing “%” look like it was a copy/paste error.

December 28, 2011

rkintada rkintada
Lab Rat
8 posts

Thanks to Volker as well for the reply.

 
  ‹‹ [Solved] QNetworkAccessManager/QThread/Signals & Slots      [SOLVED] how to get tab index when only text is known? ››

You must log in to post a reply. Not a member yet? Register here!