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.
  • W Offline
    W Offline
    welsey
    wrote on last edited by
    #1

    I get something wrong when i use qDebug to output message base point to QString::toLocal8Bit().data(); the source code is like this:
    QString str = "X";

    void *ptr1 = (void*)str.toLocal8Bit().data();
    void *ptr2 = (void*)str.toLocal8Bit().data();
    void *ptr3 = (void*)str.toLocal8Bit().data();
    void *ptr4 = (void*)str.toLocal8Bit().data();
    
    qDebug()<<ptr1<<*(unsigned char*)ptr1;
    qDebug()<<ptr2<<*(unsigned char*)ptr2;
    qDebug()<<ptr3<<*(unsigned char*)ptr3;
    qDebug()<<ptr4<<*(unsigned char*)ptr4;
    

    and then i got the result:
    0x10862c8 88
    0x10862c8 80
    0x10862c8 80
    0x10862c8 80
    would you encountered the result like this? please tell me how to deal with it,thanks a lot!

    JonBJ 1 Reply Last reply
    0
    • W welsey

      I get something wrong when i use qDebug to output message base point to QString::toLocal8Bit().data(); the source code is like this:
      QString str = "X";

      void *ptr1 = (void*)str.toLocal8Bit().data();
      void *ptr2 = (void*)str.toLocal8Bit().data();
      void *ptr3 = (void*)str.toLocal8Bit().data();
      void *ptr4 = (void*)str.toLocal8Bit().data();
      
      qDebug()<<ptr1<<*(unsigned char*)ptr1;
      qDebug()<<ptr2<<*(unsigned char*)ptr2;
      qDebug()<<ptr3<<*(unsigned char*)ptr3;
      qDebug()<<ptr4<<*(unsigned char*)ptr4;
      

      and then i got the result:
      0x10862c8 88
      0x10862c8 80
      0x10862c8 80
      0x10862c8 80
      would you encountered the result like this? please tell me how to deal with it,thanks a lot!

      JonBJ Online
      JonBJ Online
      JonB
      wrote on last edited by JonB
      #2

      @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 1 Reply Last reply
      0
      • 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 Online
            JonBJ Online
            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 Online
              JonBJ Online
              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 Online
                      JonBJ Online
                      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 Online
                          JonBJ Online
                          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