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.
  • 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