1

I have a code snippet to test a code bug.

    #include <QCoreApplication>
    #include <QDebug>

    int main(int argc, char *argv[])
    {
        QCoreApplication a(argc, argv);
        QString name = QString("Lucy");
        QString interest = QString("Swimming");

        const char* strInterest = interest.toLatin1().data();
        const char* strName = name.toLatin1().data();

        qDebug()<<"QName: "<<name<<" QInterest: "<<interest;
        qDebug()<<"Name: "<<strName<<" Interest: "<<strInterest;

        return a.exec();
    }

The result on macOS: QName: "Lucy" QInterest: "Swimming" Name: Lucy Interest: .

The result on ubuntu: root@:test$ ./testCharP QName: "Lucy" QInterest: "Swimming" Name: Interest: .
As you can see, the converted buffer does not be saved as a const value, what about the problem? Also, there are some differences between these two OS, what is the cause maybe?.

Izuka
  • 2,572
  • 5
  • 29
  • 34
user3857893
  • 63
  • 1
  • 5

2 Answers2

4

What you are observing is undefined behavior.

The call to toLatin1() creates a temporary QByteArray, which is destroyed immediately after that line, since you do not store it. The pointer obtained by data() is left dangling and might or might not print something useful.

Correct version:

const QByteArray& latinName = name.toLatin1();
const char* strName = latinName.data();
SteakOverflow
  • 1,953
  • 13
  • 26
1

The problem is that the toLatin1 function returns a QByteArray object, and by not saving this object it will be temporary and be destructed once the assignment have been done.

That means your pointer points to some data that no longer exists, and dereferencing it will lead to undefined behavior.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
  • Oh, I see. Could I use "strcpy" to copy the buffer value of the QByteArray? I have test it, it works. – user3857893 Dec 13 '17 at 08:13
  • @user3857893 Yes you could. But then you need to allocate memory, and not forget the string terminator. I also wonder *why* you need this pointer? If you just are going to pass it to a C function then it's okay to use temporary objects like you do (as long as you do e.g. `name.toLatin1().data()` for the *argument* expression). – Some programmer dude Dec 13 '17 at 08:15
  • You are right, because I have many places to use this value as a type of "const char *", so I save the value in a const variable. – user3857893 Dec 13 '17 at 08:21