Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. qDebug output the message from point to QString::toLocal8Bit().data();
Forum Updated to NodeBB v4.3 + New Features

qDebug output the message from point to QString::toLocal8Bit().data();

Scheduled Pinned Locked Moved Solved General and Desktop
13 Posts 4 Posters 1.3k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • JonBJ JonB

    @welsey
    What is wrong? qDebug() is showing the data() as bytes (not chars), 88 looks about right for the letter X....

    If you mean why does it show different values (assuming your output is indeed accurate), that must be to do with toLocal8Bit().data() returning a temporary copy, and that being altered after you have last referenced it, maybe? E.g. try reversing the order of your output lines so it goes in order from ptr4 to ptr1, does it then get ptr4 right and the others wrong?

    W Offline
    W Offline
    welsey
    wrote on last edited by
    #3

    @jonb thanks for your reply, the first is quite right, but the last three is wrong, i cannot understand it.

    JonBJ 1 Reply Last reply
    0
    • SGaistS Offline
      SGaistS Offline
      SGaist
      Lifetime Qt Champion
      wrote on last edited by
      #4

      Hi,

      void *ptr1 = (void*)str.toLocal8Bit().data(); this line and the other similar are likely giving you a warning.

      From a lifetime point of view the QByteArray returned by toLocal8Bit ends at the the semicolon. The fact that the memory address you get is the same for all these calls is just luck and as you have seen, the content of that memory segment may have changed because the object that used to use it has already been destroyed and thus it may have been reused for something else.

      If you want to play with the data contained in that QByteArray you have to do it like this:

      QByteArray local8BitRepresentation = str.toLocal8Bit();
      void *ptr1 = (void*)local8BitRepresentation.data();
      void *ptr2 = (void*)local8BitRepresentation.data();
      // etc.
      

      Interested in AI ? www.idiap.ch
      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

      JonBJ W 2 Replies Last reply
      4
      • W welsey

        @jonb thanks for your reply, the first is quite right, but the last three is wrong, i cannot understand it.

        JonBJ Offline
        JonBJ Offline
        JonB
        wrote on last edited by JonB
        #5

        @welsey
        I had already appended to my reply about this. Read that. I believe we must be talking about temporary areas here, think about where these toLocal8Bit() results are getting stored/released?

        I see @SGaist is confirming this, and suggesting you need to put it into a named QByteArray so that you can play with it without it getting disposed in the middle of what you're doing.

        W 1 Reply Last reply
        1
        • SGaistS SGaist

          Hi,

          void *ptr1 = (void*)str.toLocal8Bit().data(); this line and the other similar are likely giving you a warning.

          From a lifetime point of view the QByteArray returned by toLocal8Bit ends at the the semicolon. The fact that the memory address you get is the same for all these calls is just luck and as you have seen, the content of that memory segment may have changed because the object that used to use it has already been destroyed and thus it may have been reused for something else.

          If you want to play with the data contained in that QByteArray you have to do it like this:

          QByteArray local8BitRepresentation = str.toLocal8Bit();
          void *ptr1 = (void*)local8BitRepresentation.data();
          void *ptr2 = (void*)local8BitRepresentation.data();
          // etc.
          
          JonBJ Offline
          JonBJ Offline
          JonB
          wrote on last edited by
          #6

          @sgaist
          I'd like to press you on this, as it's quite interesting (to me at least!). Remember I am not a Qt C++-er, so I cannot test for myself.

          Looking at the code. What is it that can actually change after line 1 and before line 2:

          qDebug()<<ptr1<<*(unsigned char*)ptr1;
          qDebug()<<ptr2<<*(unsigned char*)ptr2;
          

          ? Qt does not do resource releasing in a separate thread. So I see only two possibilities as to how the second line can see different content from the first one:

          • There is an actual instruction in the machine code after line 1 which causes release. But I don't see that there will be?

          • It is the fact that the user called a Qt function like qDebug(), which itself uses Qt stuff which causes the context to be released/changed? It must be this?? So if OP had instead written:

          unsigned char c1 = *(unsigned char*)ptr1; 
          unsigned char c2 = *(unsigned char*)ptr2; 
          qDebug()<<ptr1<<c1;
          qDebug()<<ptr2<<c2;
          

          then the results would be the same?

          SGaistS 1 Reply Last reply
          0
          • SGaistS SGaist

            Hi,

            void *ptr1 = (void*)str.toLocal8Bit().data(); this line and the other similar are likely giving you a warning.

            From a lifetime point of view the QByteArray returned by toLocal8Bit ends at the the semicolon. The fact that the memory address you get is the same for all these calls is just luck and as you have seen, the content of that memory segment may have changed because the object that used to use it has already been destroyed and thus it may have been reused for something else.

            If you want to play with the data contained in that QByteArray you have to do it like this:

            QByteArray local8BitRepresentation = str.toLocal8Bit();
            void *ptr1 = (void*)local8BitRepresentation.data();
            void *ptr2 = (void*)local8BitRepresentation.data();
            // etc.
            
            W Offline
            W Offline
            welsey
            wrote on last edited by
            #7

            @sgaist yeah, it's right, i think this is the answer, thanks a lot.

            1 Reply Last reply
            0
            • JonBJ JonB

              @sgaist
              I'd like to press you on this, as it's quite interesting (to me at least!). Remember I am not a Qt C++-er, so I cannot test for myself.

              Looking at the code. What is it that can actually change after line 1 and before line 2:

              qDebug()<<ptr1<<*(unsigned char*)ptr1;
              qDebug()<<ptr2<<*(unsigned char*)ptr2;
              

              ? Qt does not do resource releasing in a separate thread. So I see only two possibilities as to how the second line can see different content from the first one:

              • There is an actual instruction in the machine code after line 1 which causes release. But I don't see that there will be?

              • It is the fact that the user called a Qt function like qDebug(), which itself uses Qt stuff which causes the context to be released/changed? It must be this?? So if OP had instead written:

              unsigned char c1 = *(unsigned char*)ptr1; 
              unsigned char c2 = *(unsigned char*)ptr2; 
              qDebug()<<ptr1<<c1;
              qDebug()<<ptr2<<c2;
              

              then the results would be the same?

              SGaistS Offline
              SGaistS Offline
              SGaist
              Lifetime Qt Champion
              wrote on last edited by
              #8

              @jonb Between these two lines you can have lots of stuff happening. Don't forget that there's a lot of things going on your machine while you execute your program.

              As for memory releasing, it's nothing Qt specific. The object is destroyed but you can have the next one re-created in the same place or a different one.

              Interested in AI ? www.idiap.ch
              Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

              JonBJ 1 Reply Last reply
              1
              • JonBJ JonB

                @welsey
                I had already appended to my reply about this. Read that. I believe we must be talking about temporary areas here, think about where these toLocal8Bit() results are getting stored/released?

                I see @SGaist is confirming this, and suggesting you need to put it into a named QByteArray so that you can play with it without it getting disposed in the middle of what you're doing.

                W Offline
                W Offline
                welsey
                wrote on last edited by
                #9

                @JonB i tested it and it worked;

                1 Reply Last reply
                0
                • SGaistS SGaist

                  @jonb Between these two lines you can have lots of stuff happening. Don't forget that there's a lot of things going on your machine while you execute your program.

                  As for memory releasing, it's nothing Qt specific. The object is destroyed but you can have the next one re-created in the same place or a different one.

                  JonBJ Offline
                  JonBJ Offline
                  JonB
                  wrote on last edited by
                  #10

                  @sgaist

                  @jonb Between these two lines you can have lots of stuff happening. Don't forget that there's a lot of things going on your machine while you execute your program.

                  Sorry, I don't get this at all. (It may be that this is a discussion for another topic...) So far as I am aware, there is nothing which can/will change the memory area inside a process from "other things going on on machine" in the middle of normal instructions inside one's code. Unless there is another thread operating here (which I don't think there is), nothing will happen to its memory space which cannot be seen from direct instructions inside the code where we are, and I don't see anything which could do that. The fact that I believe the OP is posting it does not get altered if he tries my alternative code which does not call qDebug() between the two lines proves that the cause is whatever is happening inside qDebug() (within the process) which gives rise to the behaviour witnessed.

                  aha_1980A 1 Reply Last reply
                  0
                  • JonBJ JonB

                    @sgaist

                    @jonb Between these two lines you can have lots of stuff happening. Don't forget that there's a lot of things going on your machine while you execute your program.

                    Sorry, I don't get this at all. (It may be that this is a discussion for another topic...) So far as I am aware, there is nothing which can/will change the memory area inside a process from "other things going on on machine" in the middle of normal instructions inside one's code. Unless there is another thread operating here (which I don't think there is), nothing will happen to its memory space which cannot be seen from direct instructions inside the code where we are, and I don't see anything which could do that. The fact that I believe the OP is posting it does not get altered if he tries my alternative code which does not call qDebug() between the two lines proves that the cause is whatever is happening inside qDebug() (within the process) which gives rise to the behaviour witnessed.

                    aha_1980A Offline
                    aha_1980A Offline
                    aha_1980
                    Lifetime Qt Champion
                    wrote on last edited by aha_1980
                    #11

                    @jonb

                    The main problem with the code void *ptr1 = (void*)str.toLocal8Bit().data(); is, that ptr1 is not valid.

                    Why is this? str.toLocal8Bit() creates a (temporary) QByteArray, which we could assign to a variable: QByteArray b = str.toLocal8Bit(); That would be a completely valid operation. Afterwards, we could even get a valid pointer to this array:

                    QByteArray b = str.toLocal8Bit();
                    void *ptr1 = (void*)b.data();
                    

                    Here ptr1 would be valid as long as b is valid (until the scope is closed).

                    So, why is void *ptr1 = (void*)str.toLocal8Bit().data(); wrong?

                    Because the temporary QByteArray is created and destroyed in the same line, hence the ptr1 points to invalid memory. Accessing this memory is undefined behavior. The object may still be there (and everything works) or not (and everything crashes).

                    Edit: Side note for completeness: You can use something like const QByteArray &b = str.toLocal8Bit(); (holding a reference to the temporary object). In this case, the compiler knows what you are doing and extends the lifetime of the temporary QByteArray until b goes out of scope.

                    But this only works for references!

                    Regards

                    Qt has to stay free or it will die.

                    JonBJ 1 Reply Last reply
                    1
                    • aha_1980A aha_1980

                      @jonb

                      The main problem with the code void *ptr1 = (void*)str.toLocal8Bit().data(); is, that ptr1 is not valid.

                      Why is this? str.toLocal8Bit() creates a (temporary) QByteArray, which we could assign to a variable: QByteArray b = str.toLocal8Bit(); That would be a completely valid operation. Afterwards, we could even get a valid pointer to this array:

                      QByteArray b = str.toLocal8Bit();
                      void *ptr1 = (void*)b.data();
                      

                      Here ptr1 would be valid as long as b is valid (until the scope is closed).

                      So, why is void *ptr1 = (void*)str.toLocal8Bit().data(); wrong?

                      Because the temporary QByteArray is created and destroyed in the same line, hence the ptr1 points to invalid memory. Accessing this memory is undefined behavior. The object may still be there (and everything works) or not (and everything crashes).

                      Edit: Side note for completeness: You can use something like const QByteArray &b = str.toLocal8Bit(); (holding a reference to the temporary object). In this case, the compiler knows what you are doing and extends the lifetime of the temporary QByteArray until b goes out of scope.

                      But this only works for references!

                      Regards

                      JonBJ Offline
                      JonBJ Offline
                      JonB
                      wrote on last edited by JonB
                      #12

                      @aha_1980
                      In the politest way. I do understand all of this. It is the answer to why the OP should not be writing the code he did. It is not the answer to what I am interested in, which is how the value at a given memory location gets changed between two consecutive statements which read it. My question is what changes it between these two lines (simply because I am interested).

                      It seems to me that what the OP reports proves (to me) that it is the qDebug() on the first line which, as a (quite understandable) side-effect, is writing to the memory location. I did not spot that at first. I do not see what else it can be.

                      aha_1980A 1 Reply Last reply
                      0
                      • JonBJ JonB

                        @aha_1980
                        In the politest way. I do understand all of this. It is the answer to why the OP should not be writing the code he did. It is not the answer to what I am interested in, which is how the value at a given memory location gets changed between two consecutive statements which read it. My question is what changes it between these two lines (simply because I am interested).

                        It seems to me that what the OP reports proves (to me) that it is the qDebug() on the first line which, as a (quite understandable) side-effect, is writing to the memory location. I did not spot that at first. I do not see what else it can be.

                        aha_1980A Offline
                        aha_1980A Offline
                        aha_1980
                        Lifetime Qt Champion
                        wrote on last edited by
                        #13

                        @jonb said in qDebug output the message from point to QString::toLocal8Bit().data();:

                        It is not the answer to what I am interested in, which is how the value at a given memory location gets changed between two consecutive statements which read it. My question is what changes it between these two lines (simply because I am interested).

                        And that's what I liked to point out: we are talking about accessing invalid memory. You simply cannot do that.

                        Qt has to stay free or it will die.

                        1 Reply Last reply
                        0

                        • Login

                        • Login or register to search.
                        • First post
                          Last post
                        0
                        • Categories
                        • Recent
                        • Tags
                        • Popular
                        • Users
                        • Groups
                        • Search
                        • Get Qt Extensions
                        • Unsolved