QString::fromStdString/toStdString wrong behavior.

  • Greetings!

    I have some std::string and trying to create a QString from it. Next I'm trying to get std::string back, but I get different string.

    @const char* c1 = s1.data(); // s1 - std::string
    const char* c2 = QString::fromStdString(s1).toStdString().data();
    int comp = strcmp(c1, c2); // -1 in my case@

    @QString::fromStdString(s1).toStdString() == s1 // false@

    The docs says that QT should be configured with STL compatibility, but as far I know it's done automatically.

  • Moderators

    const char* c2 = QString::fromStdString(s1).toStdString().data();
    This is a (common) mistake and a bug.
    At the ; the temporary returned by toStdString is destroyed so c2 points to invalid memory region.

  • Thank you, you're right. But anyway, with lvalues the behavior is the same. Or take a look at the second example.

  • Moderators

    Works for me. What string do you have and what encoding does it use? Qt assumes utf-8 when using fromStdString. If it's not utf-8 the resulting QString might become garbage.

  • To be honest, I don't know the encoding. I'm using a string from protobuf's SerializeToString().

  • We use SerializeToArray() into a QByteArray, maybe that's an alternative for you.

  • Yeah. I'm using it right now. Just wondering what's wrong with a string.

  • Moderators

    If you don't know the encoding I would plug the debugger and see what the data is in there. Print that stuff out before and after the conversion. See if there are any \0 or non-utf8 characters etc. Basically eyeball the problem ;)

  • Yeah, tried this. Can't understand. Protobuf docs don't say what encoding do they use. In memory editor in debugger I can see that string from QString have some extra bytes.

  • Moderators

    The docs of the fromStdString() say that it uses fromUtf8 which expects a null terminated string. This is also what std::string contains. If the extra bytes you see are at the end it would mean that SerializeToString() somehow creates an invalid std::string object.

    SerializeToArray takes the size parameter explicitly thus probably avoiding the problem.

    A though came to me. How are you linking to the protobuf? Was it built using the same compiler version and settings as your app? The sizes and layout of std::string varies between compiler and STL versions. Maybe you're dealing with corrupted string objects?

  • No, the compiler is the same. It's hard to reproduce a problem because with some test string everything works. The problem arised only with serialized string. And the extra bytes I found in the beginning and in the end. SerializeToArray is working for me.

Log in to reply