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. Random crash with QVector
Forum Updated to NodeBB v4.3 + New Features

Random crash with QVector

Scheduled Pinned Locked Moved Unsolved General and Desktop
13 Posts 6 Posters 1.4k Views 4 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.
  • L Offline
    L Offline
    Loc888
    wrote on last edited by Loc888
    #1

    I got some random crashes, when i use QVector, for unknown reason.
    So when i do this:

    QVector<int> data;
    int a = 120;
    int b = 546;
    int c = 157;
    data.append(a);
    data.append(b);
    data.append(c);

    Now, here the problem starts. I want to set the pointer, to the internal element of QVector. So:

    int* p = &data[0];

    Now, for some reasons, it does work at the beginning, but after just few elements added, it stops. The pointer gets changed from what i was able to see, so i fixed this by using a pointer to another pointer.

    What is the reason of that? Also, i want to make sure, that this fix for this issue, is safe, that it's not gonna crash anymore.

    JKSHJ 1 Reply Last reply
    0
    • Kent-DorfmanK Offline
      Kent-DorfmanK Offline
      Kent-Dorfman
      wrote on last edited by Kent-Dorfman
      #2

      The address of the first element is going to change as you "append" elements and it has to reallocate memory to allow for a larger continguous space.

      Never expect that &data[0] is constant. A resize(), either explicit or implicit MAY cause a reallocation and invalidate the saved address of the first element.

      1 Reply Last reply
      8
      • L Loc888

        I got some random crashes, when i use QVector, for unknown reason.
        So when i do this:

        QVector<int> data;
        int a = 120;
        int b = 546;
        int c = 157;
        data.append(a);
        data.append(b);
        data.append(c);

        Now, here the problem starts. I want to set the pointer, to the internal element of QVector. So:

        int* p = &data[0];

        Now, for some reasons, it does work at the beginning, but after just few elements added, it stops. The pointer gets changed from what i was able to see, so i fixed this by using a pointer to another pointer.

        What is the reason of that? Also, i want to make sure, that this fix for this issue, is safe, that it's not gonna crash anymore.

        JKSHJ Offline
        JKSHJ Offline
        JKSH
        Moderators
        wrote on last edited by
        #3

        @Loc888 Can you please explain your goal? Why do you want the pointer to an internal element of QVector?

        Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

        L 1 Reply Last reply
        2
        • JKSHJ JKSH

          @Loc888 Can you please explain your goal? Why do you want the pointer to an internal element of QVector?

          L Offline
          L Offline
          Loc888
          wrote on last edited by
          #4

          @JKSH Because i want to point to the data.. There are objects and things happening to them, so i want those things to happen only at the selected object. Because the objects are added dynamically, i had to use vector, and yes i know i could use pointers in the vector, but because i already program it for non-pointer vector, i choose that instead of changing it, i will simply just use pointer to the direct data.

          jsulmJ 1 Reply Last reply
          0
          • L Loc888

            @JKSH Because i want to point to the data.. There are objects and things happening to them, so i want those things to happen only at the selected object. Because the objects are added dynamically, i had to use vector, and yes i know i could use pointers in the vector, but because i already program it for non-pointer vector, i choose that instead of changing it, i will simply just use pointer to the direct data.

            jsulmJ Offline
            jsulmJ Offline
            jsulm
            Lifetime Qt Champion
            wrote on last edited by
            #5

            @Loc888 As @Kent-Dorfman pointed out if you add data then QVector will sometimes reallocate memory and move vector data into new memory to resize the vector. So, all pointers will become invalid.
            Instead of using pointers, why don't you use indexes inside the vector? The indexes will not change as the elements do not change their position inside vector.

            https://forum.qt.io/topic/113070/qt-code-of-conduct

            L 1 Reply Last reply
            5
            • jsulmJ jsulm

              @Loc888 As @Kent-Dorfman pointed out if you add data then QVector will sometimes reallocate memory and move vector data into new memory to resize the vector. So, all pointers will become invalid.
              Instead of using pointers, why don't you use indexes inside the vector? The indexes will not change as the elements do not change their position inside vector.

              L Offline
              L Offline
              Loc888
              wrote on last edited by
              #6

              @jsulm What you mean by indexes?

              jsulmJ 1 Reply Last reply
              0
              • L Loc888

                @jsulm What you mean by indexes?

                jsulmJ Offline
                jsulmJ Offline
                jsulm
                Lifetime Qt Champion
                wrote on last edited by
                #7

                @Loc888

                data[0]; // 0 is the index in the vector
                

                https://forum.qt.io/topic/113070/qt-code-of-conduct

                L 1 Reply Last reply
                0
                • mrdebugM Offline
                  mrdebugM Offline
                  mrdebug
                  wrote on last edited by mrdebug
                  #8

                  Please have a look

                      QVector<int> aVector;
                      aVector.push_back(254);
                      int *p= &aVector.data()[0];
                      *p= 123;
                      qDebug() << aVector.at(0);
                  
                  

                  The output is 123 so in order to get the pointer to a specific QVector element please use

                  &aVector.data()[x]
                  

                  Need programmers to hire?
                  www.labcsp.com
                  www.denisgottardello.it
                  GMT+1
                  Skype: mrdebug

                  1 Reply Last reply
                  0
                  • Kent-DorfmanK Offline
                    Kent-DorfmanK Offline
                    Kent-Dorfman
                    wrote on last edited by Kent-Dorfman
                    #9

                    In defense of the OP, there are valid reasons for getting the address of the first element. You just need to treat it as a temporary, and understand that any operation that modifies the size of the vector may invalidate it so DONT SAVE IT. REREAD IT when necessary....and data() is just an alias for &data[0] with the perk of possibly being const, but I'm not gonna touch the whole "what is const" discussion.

                    1 Reply Last reply
                    1
                    • jsulmJ jsulm

                      @Loc888

                      data[0]; // 0 is the index in the vector
                      
                      L Offline
                      L Offline
                      Loc888
                      wrote on last edited by
                      #10

                      @jsulm I can't do that, because the data what i use, is not declared there. I didn't want to give a pointer to the whole vector, because it will just create some mess.

                      Each object from class A, have the data for class B, which is just the display class of a particular object inside the vector. Class B is also a vector. If i pass the whole vector pointer, then i will have to specifie which index of A belongs to the index of B.

                      Basically it's just few lines of code, to send the a pointer to b. I wanted to split the data from the UI, so that's why they are not inside 1 class.

                      JKSHJ 1 Reply Last reply
                      0
                      • Kent-DorfmanK Offline
                        Kent-DorfmanK Offline
                        Kent-Dorfman
                        wrote on last edited by
                        #11

                        @Loc888 so pass around a reference to the whole container and then pull the data from it using the indexes, whenever you need to, and for whatever range suits your fancy. With the minimal information you've shared, my spidey-sense tells me you are over-thingking your problem.

                        1 Reply Last reply
                        4
                        • Christian EhrlicherC Online
                          Christian EhrlicherC Online
                          Christian Ehrlicher
                          Lifetime Qt Champion
                          wrote on last edited by Christian Ehrlicher
                          #12

                          @Loc888 said in Random crash with QVector:

                          I didn't want to give a pointer to the whole vector

                          You're aware that you did exactly this in your first post?

                          int* p = &data[0];

                          Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                          Visit the Qt Academy at https://academy.qt.io/catalog

                          1 Reply Last reply
                          1
                          • L Loc888

                            @jsulm I can't do that, because the data what i use, is not declared there. I didn't want to give a pointer to the whole vector, because it will just create some mess.

                            Each object from class A, have the data for class B, which is just the display class of a particular object inside the vector. Class B is also a vector. If i pass the whole vector pointer, then i will have to specifie which index of A belongs to the index of B.

                            Basically it's just few lines of code, to send the a pointer to b. I wanted to split the data from the UI, so that's why they are not inside 1 class.

                            JKSHJ Offline
                            JKSHJ Offline
                            JKSH
                            Moderators
                            wrote on last edited by JKSH
                            #13

                            @Loc888 said in Random crash with QVector:

                            I wanted to split the data from the UI, so that's why they are not inside 1 class.

                            It is good that you want to keep your code organized and split the data from the UI.

                            Be warned though: When you try to pass an internal data pointer from Class B to Class A, you are breaking encapsulation which is bad (see https://stackoverflow.com/questions/16014290/simple-way-to-understand-encapsulation-and-abstraction )

                            To maintain encapsulation, don't pass a pointer to a vector element. Don't pass the whole vector either. Instead, pass the index only, and design some class methods to let you access the data easily. For example:

                            class Database {
                            public:
                                // TODO: Check that the index is valid before accessing m_data
                                int getData(int index) { return m_data[index]; }
                                void setData(int index, int newValue) { m_data[index] = newValue; }
                            
                            private:
                                QVector<int> m_data;
                            };
                            

                            Your GUI class should call the getData() and setData() functions instead of using a pointer to access the vector's data.

                            Note: Qt's Model View classes are designed this way. A Model contains the data; a View is the UI.

                            Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

                            1 Reply Last reply
                            5

                            • Login

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