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. Trying to fix memory leak due to QGraphicsScene
Forum Updated to NodeBB v4.3 + New Features

Trying to fix memory leak due to QGraphicsScene

Scheduled Pinned Locked Moved Unsolved General and Desktop
qt 5.5.1c++memory leak
13 Posts 3 Posters 7.8k 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.
  • Akito_KamiA Offline
    Akito_KamiA Offline
    Akito_Kami
    wrote on last edited by Akito_Kami
    #1

    I am making a program to load a large amount of images.

    In one function I am instantiating an object

    function QtProject::load(QString path){
        QGraphicsScene* scene = new QGraphicsScene;
        scene = QPixmap(path);
       ui->qgraphicsview->setScene(scene)
    }
    

    and in function 2 I am trying to load the next set of image on keypress.

    function QtProject::next(){
        path = test[page++];
        load(path);
    }
    

    However doing so, leaves the previous image object in ram and the variable is redeclared and thus creates a memory leak. How do I solve this?

    1 Reply Last reply
    0
    • ProteosP Offline
      ProteosP Offline
      Proteos
      wrote on last edited by Proteos
      #2

      The thing is that in function 1 you create a "temporary" pointer to create a new GraphicsScene on the heap and then you add it on you ui's graphicsview. Which means that the only way to access your scene after the end of the function load is to use the method QGraphicsScene::scene();
      So if you load a new scene that will replace the previous one, you will loose your only reference to it, hence the memory leak.

      We need more information about your aim if you want accurate help. Yet, I can suggest that you create an array (or vector if you want a resizable container) of pointers (as you need pointers in methods like setScence(QGraphicsScene*) ) that will save a reference to the images you load so that you can still delete them if you need.

      1 Reply Last reply
      1
      • Akito_KamiA Offline
        Akito_KamiA Offline
        Akito_Kami
        wrote on last edited by
        #3

        @Proteos said:

        a "temporary" pointer to create a new GraphicsScene on the heap and then you add it on you ui's graphicsview. Which means that the only way to access your scene after the end of the function load is to use the method QGraphicsScene::scene();

        I tried to create a pointer outside of the function for the scene object, but it instantly crashes the program

        ProteosP 1 Reply Last reply
        0
        • Akito_KamiA Akito_Kami

          @Proteos said:

          a "temporary" pointer to create a new GraphicsScene on the heap and then you add it on you ui's graphicsview. Which means that the only way to access your scene after the end of the function load is to use the method QGraphicsScene::scene();

          I tried to create a pointer outside of the function for the scene object, but it instantly crashes the program

          ProteosP Offline
          ProteosP Offline
          Proteos
          wrote on last edited by Proteos
          #4

          @Akito_Kami where exactly outside the function did you declare your pointer ?

          But it won't solve the memory leak as your pointer's value will change.

          Akito_KamiA 1 Reply Last reply
          0
          • ProteosP Proteos

            @Akito_Kami where exactly outside the function did you declare your pointer ?

            But it won't solve the memory leak as your pointer's value will change.

            Akito_KamiA Offline
            Akito_KamiA Offline
            Akito_Kami
            wrote on last edited by
            #5

            @Proteos The header file and then the class file

            ProteosP 1 Reply Last reply
            0
            • Akito_KamiA Akito_Kami

              @Proteos The header file and then the class file

              ProteosP Offline
              ProteosP Offline
              Proteos
              wrote on last edited by Proteos
              #6

              @Akito_Kami The problem is not in the pointer (recreating it or changing its value will cause the same issue) but in object's lifetime.

              When you create an object using the 'new' operator, your object is created on the heap and won't be destroyed until you ask for it with the instruction 'delete'.

              Which mean that the following situation will always create a memory leak :

              void function()
              {
              object* p = new object();
              }

              you will loose you pointer at the end of the function and the object will remain unaccessible in memory.

              Declaring a pointer oustide the function (as global or as member) will create a memory leak if you change it's value :

              object* p;

              void function()
              {
              p = new object();
              }

              In this case, if you call the function twice, the object created the first time will be lost in memory.

              So if you want to avoid memory leaks, you have to worry about always keeping a way to access the object you create using 'new'.
              If you need to create 30 objects using new, then you will need to store 30 pointers somewhere. Otherwise you will create memory leaks unless you use the instruction delete before changing your pointer's value.

              Was my explanation clear ? :)

              1 Reply Last reply
              0
              • Akito_KamiA Offline
                Akito_KamiA Offline
                Akito_Kami
                wrote on last edited by Akito_Kami
                #7

                @Proteos Making an unlimited number of pointers isn't feasible because I have no idea how many images will be loaded in the first place. Is there a way for automatic garbage collection by Qt?

                ProteosP 1 Reply Last reply
                0
                • Akito_KamiA Akito_Kami

                  @Proteos Making an unlimited number of pointers isn't feasible because I have no idea how many images will be loaded in the first place. Is there a way for automatic garbage collection by Qt?

                  ProteosP Offline
                  ProteosP Offline
                  Proteos
                  wrote on last edited by Proteos
                  #8

                  @Akito_Kami Not knowing how many images you will load is not a problem ! You just have to use a vector (from Qt or STL as you wish) which is a kind of resizable array.
                  You can declare it empty as a class member, and then add images in it with its methods push_back or insert.
                  Here is the documentation of QVectors : http://doc.qt.io/qt-5/qvector.html

                  Code exemple :

                  in header:
                  QVector<object*> yourVector;

                  in class file:
                  void function1()
                  {
                  yourVector.push_back(new object());
                  }

                  EDIT : the solution I'm giving actually fits a programm in which you want to keep many images in memory at the same time (for exemple if you need to reuse some them at different times). But if you only need one at a time and don't want to keep others in memory, just use the instruction delete before loading a new image.
                  If you do not want to worry about the delete instruction you can use smart pointers (a lot of documentation on the Internet) whose destructors automatically delete the pointed object (provided the pointer is destructed).

                  Akito_KamiA 1 Reply Last reply
                  1
                  • ProteosP Proteos

                    @Akito_Kami Not knowing how many images you will load is not a problem ! You just have to use a vector (from Qt or STL as you wish) which is a kind of resizable array.
                    You can declare it empty as a class member, and then add images in it with its methods push_back or insert.
                    Here is the documentation of QVectors : http://doc.qt.io/qt-5/qvector.html

                    Code exemple :

                    in header:
                    QVector<object*> yourVector;

                    in class file:
                    void function1()
                    {
                    yourVector.push_back(new object());
                    }

                    EDIT : the solution I'm giving actually fits a programm in which you want to keep many images in memory at the same time (for exemple if you need to reuse some them at different times). But if you only need one at a time and don't want to keep others in memory, just use the instruction delete before loading a new image.
                    If you do not want to worry about the delete instruction you can use smart pointers (a lot of documentation on the Internet) whose destructors automatically delete the pointed object (provided the pointer is destructed).

                    Akito_KamiA Offline
                    Akito_KamiA Offline
                    Akito_Kami
                    wrote on last edited by
                    #9

                    @Proteos Quick question. if I delete something at index 0 of the vector, does it automatically shift the objects in the vector? or does push back do it for me?

                    ProteosP 1 Reply Last reply
                    0
                    • Akito_KamiA Akito_Kami

                      @Proteos Quick question. if I delete something at index 0 of the vector, does it automatically shift the objects in the vector? or does push back do it for me?

                      ProteosP Offline
                      ProteosP Offline
                      Proteos
                      wrote on last edited by Proteos
                      #10

                      @Akito_Kami If you use the methods QVector::remove(int index) or QVector::removeAt(int index) for any object, it will indeed readjust every indexes of the vector.

                      If you remove an object at index 0, then the object at index 1 will take its place becoming object 0 and so on.

                      But if your vector contains pointers, you will need to delete the object pointed (deleting does not destroy the pointer), so if you want to remove the pointer at index 0, you have to do this :

                      delete yourVector.at(0); // destroys the pointed object
                      yourVector.remove(0); // destroys the pointer and shift other indexes

                      1 Reply Last reply
                      0
                      • A Offline
                        A Offline
                        Asperamanca
                        wrote on last edited by Asperamanca
                        #11
                        • Why do you instantiate more than one GraphicsScene? You can only have one scene per view. What you probably want is to instantiate and add multiple QGraphicsItem-derived objects
                        • What is the line scene = path; supposed to do?
                        Akito_KamiA 1 Reply Last reply
                        0
                        • A Asperamanca
                          • Why do you instantiate more than one GraphicsScene? You can only have one scene per view. What you probably want is to instantiate and add multiple QGraphicsItem-derived objects
                          • What is the line scene = path; supposed to do?
                          Akito_KamiA Offline
                          Akito_KamiA Offline
                          Akito_Kami
                          wrote on last edited by Akito_Kami
                          #12

                          @Asperamanca
                          What are you trying to say in your first question? I have a function which loads the path of the image into QGraphicsScene and then loads it in the QGraphicsView. I know I can only have one scene per view.
                          QGraphicsItem doesn't allow me to load Pixmap objects. http://doc.qt.io/qt-5/qgraphicsitem-members.html
                          Second question: Prototyping example not actual use

                          Edit: I can't understand what you meant at all in your first statement

                          A 1 Reply Last reply
                          0
                          • Akito_KamiA Akito_Kami

                            @Asperamanca
                            What are you trying to say in your first question? I have a function which loads the path of the image into QGraphicsScene and then loads it in the QGraphicsView. I know I can only have one scene per view.
                            QGraphicsItem doesn't allow me to load Pixmap objects. http://doc.qt.io/qt-5/qgraphicsitem-members.html
                            Second question: Prototyping example not actual use

                            Edit: I can't understand what you meant at all in your first statement

                            A Offline
                            A Offline
                            Asperamanca
                            wrote on last edited by
                            #13

                            @Akito_Kami
                            Your "load" function instantiates a new QGraphicsScene
                            You call it within a loop.
                            Therefore you instantiate multiple QGraphicsScenes
                            I don't see where you need to do that.

                            Also, I wrote "QGraphicsItem-derived", not "QGraphicsItem". If you want to show pixmaps, use QGraphicsPixmapItem, or implement your own version of QGraphicsItem to show a pixmap.

                            Totally unrelated: I hate my junk mail filter. Otherwise I would have answered sooner.

                            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