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. Some small questions about qt container detachment.
Qt 6.11 is out! See what's new in the release blog

Some small questions about qt container detachment.

Scheduled Pinned Locked Moved Solved General and Desktop
15 Posts 3 Posters 3.5k 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.
  • P PikaCat

    Thanks and what about question 3?

    KroMignonK Offline
    KroMignonK Offline
    KroMignon
    wrote on last edited by
    #4

    @PikaCat said in Some small questions about qt container detachment.:

    Thanks and what about question 3?

    Why should it crash?

    Code 1 will crash because you are doing things wrong.
    This code don't make sense.

    It is an old maxim of mine that when you have excluded the impossible, whatever remains, however improbable, must be the truth. (Sherlock Holmes)

    P 2 Replies Last reply
    0
    • KroMignonK KroMignon

      @PikaCat said in Some small questions about qt container detachment.:

      Thanks and what about question 3?

      Why should it crash?

      Code 1 will crash because you are doing things wrong.
      This code don't make sense.

      P Offline
      P Offline
      PikaCat
      wrote on last edited by
      #5

      @KroMignon Because once the container is detached by emplacing a new object, accessing qDebug() << "world" on the next iteration is accessing deleted data.

      1 Reply Last reply
      0
      • KroMignonK KroMignon

        @PikaCat said in Some small questions about qt container detachment.:

        Thanks and what about question 3?

        Why should it crash?

        Code 1 will crash because you are doing things wrong.
        This code don't make sense.

        P Offline
        P Offline
        PikaCat
        wrote on last edited by
        #6

        @KroMignon the code also works normally if you changes the code order sightly:

          QList<QString> test { "hello", "world" };
          for (const QString &str : test) {
            test.emplaceBack("he");
            qDebug() << str;
          }
          qDebug() << test;
        

        And it's apparently wrong because after detaching, the old container is deleted. So the QString object does not exist in the old container and you still want to get a reference of it and output the content of it.

        KroMignonK 1 Reply Last reply
        0
        • P PikaCat

          @KroMignon the code also works normally if you changes the code order sightly:

            QList<QString> test { "hello", "world" };
            for (const QString &str : test) {
              test.emplaceBack("he");
              qDebug() << str;
            }
            qDebug() << test;
          

          And it's apparently wrong because after detaching, the old container is deleted. So the QString object does not exist in the old container and you still want to get a reference of it and output the content of it.

          KroMignonK Offline
          KroMignonK Offline
          KroMignon
          wrote on last edited by KroMignon
          #7

          @PikaCat said in Some small questions about qt container detachment.:

          And it's apparently wrong because after detaching, the old container is deleted. So the QString object does not exist in the old container and you still want to get a reference of it and output the content of it.

          You are responsible of your code, so you have to be consistant.
          If you want to change a container instance during iteration, you have to use an appropriated way to iterate:

          for(int idx = 0; idx < test.length(); ++idx)
          {
          }
          

          or

          QMutableListIterator<QString> iter(test);
          while(iter.hasNext())
          {
              iter.next();
          }
          

          If you are written mess code, then you can not expect it will work.

          It is an old maxim of mine that when you have excluded the impossible, whatever remains, however improbable, must be the truth. (Sherlock Holmes)

          P 1 Reply Last reply
          0
          • KroMignonK KroMignon

            @PikaCat said in Some small questions about qt container detachment.:

            And it's apparently wrong because after detaching, the old container is deleted. So the QString object does not exist in the old container and you still want to get a reference of it and output the content of it.

            You are responsible of your code, so you have to be consistant.
            If you want to change a container instance during iteration, you have to use an appropriated way to iterate:

            for(int idx = 0; idx < test.length(); ++idx)
            {
            }
            

            or

            QMutableListIterator<QString> iter(test);
            while(iter.hasNext())
            {
                iter.next();
            }
            

            If you are written mess code, then you can not expect it will work.

            P Offline
            P Offline
            PikaCat
            wrote on last edited by PikaCat
            #8

            @KroMignon I know that code should be like that if you want to modify the container during iteration. But my orginal question is : Why accessing like I did above will not make the program crash? I just don't understand why we can access a memory that is deleted.
            It just magically feels like you apply a deep copy to the container and use the copied one to do the C++11 range loop. In that scenario, modifying the original one won't affect the loop.
            But qt's documentation said that this will only happen if you are using qt foreach loop. In range loop, it will not happen. And if that's the case, how begin() and end() iterator in the C++11 range loop works?
            see https://doc.qt.io/qt-6/foreach-keyword.html

            KroMignonK 1 Reply Last reply
            0
            • P PikaCat

              @KroMignon I know that code should be like that if you want to modify the container during iteration. But my orginal question is : Why accessing like I did above will not make the program crash? I just don't understand why we can access a memory that is deleted.
              It just magically feels like you apply a deep copy to the container and use the copied one to do the C++11 range loop. In that scenario, modifying the original one won't affect the loop.
              But qt's documentation said that this will only happen if you are using qt foreach loop. In range loop, it will not happen. And if that's the case, how begin() and end() iterator in the C++11 range loop works?
              see https://doc.qt.io/qt-6/foreach-keyword.html

              KroMignonK Offline
              KroMignonK Offline
              KroMignon
              wrote on last edited by
              #9

              @PikaCat said in Some small questions about qt container detachment.:

              But my orginal question is : Why accessing like I did above will not make the program crash?

              Because you are lucky ;)
              This code crashes with Qt 5.12 and MSVC2015 in release for example, but not in debug build.

              It may crash, but it may work depending on operating system and compiler options.

              It is an old maxim of mine that when you have excluded the impossible, whatever remains, however improbable, must be the truth. (Sherlock Holmes)

              P 1 Reply Last reply
              1
              • KroMignonK KroMignon

                @PikaCat said in Some small questions about qt container detachment.:

                But my orginal question is : Why accessing like I did above will not make the program crash?

                Because you are lucky ;)
                This code crashes with Qt 5.12 and MSVC2015 in release for example, but not in debug build.

                It may crash, but it may work depending on operating system and compiler options.

                P Offline
                P Offline
                PikaCat
                wrote on last edited by PikaCat
                #10

                @KroMignon Thanks. I finally understand the crash. One last question: After detaching, in the C++11 range loop, does the test.end() returns the new container's end iterator or the old one? Theoretically it should returns the new one. But why when it is not crash, it can still tell where is the end of this iteration by using the begin iterator of the old container and the end iterator of the new container. Which is not a normal iterator pair!

                KroMignonK artwawA 2 Replies Last reply
                0
                • P PikaCat

                  @KroMignon Thanks. I finally understand the crash. One last question: After detaching, in the C++11 range loop, does the test.end() returns the new container's end iterator or the old one? Theoretically it should returns the new one. But why when it is not crash, it can still tell where is the end of this iteration by using the begin iterator of the old container and the end iterator of the new container. Which is not a normal iterator pair!

                  KroMignonK Offline
                  KroMignonK Offline
                  KroMignon
                  wrote on last edited by
                  #11

                  @PikaCat said in Some small questions about qt container detachment.:

                  After detaching, Does the test.end() returns the new container's end iterator or the old one? Theoretically it should returns the new one. But why when it is not crash, it can still tell where is the end of this iteration by using the begin iterator of the old container and the end iterator of the new container. Which is not a normal iterator pair!

                  Don't understand the question :(
                  test.end() always returns current iterator end, problem is the detached copy which could point to an item which no more exits.

                  It is an old maxim of mine that when you have excluded the impossible, whatever remains, however improbable, must be the truth. (Sherlock Holmes)

                  P 2 Replies Last reply
                  0
                  • P PikaCat

                    @KroMignon Thanks. I finally understand the crash. One last question: After detaching, in the C++11 range loop, does the test.end() returns the new container's end iterator or the old one? Theoretically it should returns the new one. But why when it is not crash, it can still tell where is the end of this iteration by using the begin iterator of the old container and the end iterator of the new container. Which is not a normal iterator pair!

                    artwawA Offline
                    artwawA Offline
                    artwaw
                    wrote on last edited by
                    #12

                    @PikaCat Please also take a look at this article https://marcmutz.wordpress.com/effective-qt/containers/

                    It is a bit dated, some things have changed (QList is now performs as well as QVector if I understood the changes correctly) but it still gives a nice overview.

                    For more information please re-read.

                    Kind Regards,
                    Artur

                    1 Reply Last reply
                    0
                    • KroMignonK KroMignon

                      @PikaCat said in Some small questions about qt container detachment.:

                      After detaching, Does the test.end() returns the new container's end iterator or the old one? Theoretically it should returns the new one. But why when it is not crash, it can still tell where is the end of this iteration by using the begin iterator of the old container and the end iterator of the new container. Which is not a normal iterator pair!

                      Don't understand the question :(
                      test.end() always returns current iterator end, problem is the detached copy which could point to an item which no more exits.

                      P Offline
                      P Offline
                      PikaCat
                      wrote on last edited by PikaCat
                      #13

                      @KroMignon Because C++11 range loop is implemented using iterators, So for(auto &a : b) is equivalent to for(auto iter = b.begin(): iter != b.end(): ++iter) auto&a = *iter;
                      After detaching, iter is the iterator of the old container, b.end() is end iterator of the newly created container. So how is it possible to loop like that when it is not crash.

                      1 Reply Last reply
                      0
                      • KroMignonK KroMignon

                        @PikaCat said in Some small questions about qt container detachment.:

                        After detaching, Does the test.end() returns the new container's end iterator or the old one? Theoretically it should returns the new one. But why when it is not crash, it can still tell where is the end of this iteration by using the begin iterator of the old container and the end iterator of the new container. Which is not a normal iterator pair!

                        Don't understand the question :(
                        test.end() always returns current iterator end, problem is the detached copy which could point to an item which no more exits.

                        P Offline
                        P Offline
                        PikaCat
                        wrote on last edited by PikaCat
                        #14

                        @KroMignon Well, I found the answer on stackoverflow https://stackoverflow.com/questions/29578219/range-based-for-loop-vs-regular-iterator-for-loop.
                        end() is evaluated only once in the begining of range for, not every time. So for(auto &a : b) is actually equivalent to for(auto iter = b.begin(), endIter = b.end();iter !=endIter; ++iter) auto&a = *iter;
                        That perfectly explains everything.
                        Thanks anyway:) appreciate that.

                        KroMignonK 1 Reply Last reply
                        0
                        • P PikaCat

                          @KroMignon Well, I found the answer on stackoverflow https://stackoverflow.com/questions/29578219/range-based-for-loop-vs-regular-iterator-for-loop.
                          end() is evaluated only once in the begining of range for, not every time. So for(auto &a : b) is actually equivalent to for(auto iter = b.begin(), endIter = b.end();iter !=endIter; ++iter) auto&a = *iter;
                          That perfectly explains everything.
                          Thanks anyway:) appreciate that.

                          KroMignonK Offline
                          KroMignonK Offline
                          KroMignon
                          wrote on last edited by
                          #15

                          @PikaCat said in Some small questions about qt container detachment.:

                          I found the answer on stackoverflow https://stackoverflow.com/questions/29578219/range-based-for-loop-vs-regular-iterator-for-loop.
                          end() is evaluated only once in the begining of range for

                          Sorry, for me it was obvious :(

                          Thanks anyway:) appreciate that.

                          Your welcome.

                          It is an old maxim of mine that when you have excluded the impossible, whatever remains, however improbable, must be the truth. (Sherlock Holmes)

                          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