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. A little memory leak in a simple Qt program
Forum Updated to NodeBB v4.3 + New Features

A little memory leak in a simple Qt program

Scheduled Pinned Locked Moved Unsolved General and Desktop
19 Posts 5 Posters 2.4k Views 3 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.
  • Q Offline
    Q Offline
    qcoderpro
    wrote on last edited by
    #1

    Hi,
    In the following simple code we have a little memory leak until the program terminates which is related to label because anywhere we have "new" we must also have "delete" later on. But the memory leak here is harmless. How to avoid it, please? Where is the appropriate place to put "delete" on?

    #include <QApplication>
    #include <QLabel>
    
    int main(int argc, char *argv[])
    {
        QApplication app(argc, argv);
        QLabel *label = new QLabel("Hello Qt!");
        label->show();
        return app.exec();
    }
    
    1 Reply Last reply
    0
    • mrjjM Offline
      mrjjM Offline
      mrjj
      Lifetime Qt Champion
      wrote on last edited by mrjj
      #2

      Hi
      In Qt you normally put labels in a window/form and it will deleted when finished.
      please read about this system here
      https://doc.qt.io/qt-5/objecttrees.html
      So often for Qt Widgets, you do not need to call delete your self.

      This case does leak however since label has no parent and hence becomes a window.

      Since its main, you can fix this with

      int main(int argc, char *argv[])
      {
          QApplication app(argc, argv);
          QLabel label("Hello Qt!");
          label.show();
          return app.exec();
      }
      

      and it will auto clean up.

      [Edit: fixed typo SGaist]

      1 Reply Last reply
      5
      • SGaistS Offline
        SGaistS Offline
        SGaist
        Lifetime Qt Champion
        wrote on last edited by
        #3

        Hi,

        Beside @mrjj's suggestion, nothing stops you from doing the cleanup:

        int status = app.exec();
        delete label;
        return status;
        

        Interested in AI ? www.idiap.ch
        Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

        1 Reply Last reply
        4
        • Q Offline
          Q Offline
          qcoderpro
          wrote on last edited by
          #4

          So in the @mrjj version, the widget (label) is created on the stack, and it will be destructed at the program's termination. But in the @SGaist version, the widget is created on the heap and will get deleted before the program terminates. True?

          JonBJ 1 Reply Last reply
          0
          • Q qcoderpro

            So in the @mrjj version, the widget (label) is created on the stack, and it will be destructed at the program's termination. But in the @SGaist version, the widget is created on the heap and will get deleted before the program terminates. True?

            JonBJ Offline
            JonBJ Offline
            JonB
            wrote on last edited by JonB
            #5

            @qcoderpro
            Correct. Or to be more precise, in the @mrjj/stack version it will be destructed upon exit from the main() function. Which is not quite the same thing as "program's termination", it happens a little bit before the program actually terminates/exits. This may be relevant if you are checking for "memory leak", e.g. with a tool, depending on whether it checks before main() exit, after main() exit, or just before process exit.

            1 Reply Last reply
            3
            • Q Offline
              Q Offline
              qcoderpro
              wrote on last edited by qcoderpro
              #6

              One more question. When CMD, is in the program's cpp file folder and I type in "qmake -project", it writes:
              'qmake' is not recognized as an internal or external command,
              operable program or batch file
              .
              I've previously set the address to mingw on system variables: C:\Qt\5.14.2\mingw73_64\bin

              JonBJ 1 Reply Last reply
              0
              • Q qcoderpro

                One more question. When CMD, is in the program's cpp file folder and I type in "qmake -project", it writes:
                'qmake' is not recognized as an internal or external command,
                operable program or batch file
                .
                I've previously set the address to mingw on system variables: C:\Qt\5.14.2\mingw73_64\bin

                JonBJ Offline
                JonBJ Offline
                JonB
                wrote on last edited by JonB
                #7

                @qcoderpro
                What is this CMD, and why is it in "the program's cpp file folder"? Windows assumes CMD.EXE is the system command line interpreter. If you have created some CMD.EXE of your own in the current directory or higher on your PATH, bad things will happen! If by any chance your Qt program is producing a CMD.EXE you need to change that immediately!

                Q 1 Reply Last reply
                1
                • JonBJ JonB

                  @qcoderpro
                  What is this CMD, and why is it in "the program's cpp file folder"? Windows assumes CMD.EXE is the system command line interpreter. If you have created some CMD.EXE of your own in the current directory or higher on your PATH, bad things will happen! If by any chance your Qt program is producing a CMD.EXE you need to change that immediately!

                  Q Offline
                  Q Offline
                  qcoderpro
                  wrote on last edited by qcoderpro
                  #8

                  @JonB
                  No I meant the built-in Windows CMD. and by going into it I meant usig that CMD and typing the path to program's directory so that the control is there. I don't know why it didn't work.

                  This time I used the command prompt offered by Qt and it recognized the command the created the project file and makefiles.
                  Now neither "make", nor the name of the project work as command there to run the program!

                  JonBJ 1 Reply Last reply
                  0
                  • Q qcoderpro

                    @JonB
                    No I meant the built-in Windows CMD. and by going into it I meant usig that CMD and typing the path to program's directory so that the control is there. I don't know why it didn't work.

                    This time I used the command prompt offered by Qt and it recognized the command the created the project file and makefiles.
                    Now neither "make", nor the name of the project work as command there to run the program!

                    JonBJ Offline
                    JonBJ Offline
                    JonB
                    wrote on last edited by JonB
                    #9

                    @qcoderpro
                    Oh, so you mean you opened a Command Prompt window and cded to your directory.

                    So presumably normally qmake directory is not on your default PATH, hence the error message. But the Command Prompt used by Qt (Qt Creator?) is set to add that qmake directory to your PATH, so it will be found from there. Then

                    Now neither "make", nor the name of the project work as command there to run the program!

                    So look at what PATH actually is set to (and what the current directory is) when using "the command prompt offered by Qt".

                    1 Reply Last reply
                    1
                    • mrjjM Offline
                      mrjjM Offline
                      mrjj
                      Lifetime Qt Champion
                      wrote on last edited by
                      #10

                      Hi
                      after you open the cmd
                      call
                      "C:\Qt\5.14.1\msvc2017_64\bin\qtenv2.bat"
                      or
                      "C:\Qt\5.14.1\mingw73_64\bin\qtenv2.bat"
                      adjust path to math your compiler / installation
                      then its setup.

                      1 Reply Last reply
                      2
                      • Q Offline
                        Q Offline
                        qcoderpro
                        wrote on last edited by
                        #11

                        Thanks.
                        About the first post. Why have we a little leak there, please? Is it because the label won't get deleted until the program terminates? When was is it supposed to be deleted to avoid leaking?

                        And if we want to have a proper code for that example based on Qt standards, we need to firstly have a parent, like a QMainWindow or QWidget or even the QApplication itself, and then set it as the parent to the label. True?

                        mrjjM JonBJ 2 Replies Last reply
                        0
                        • Q qcoderpro

                          Thanks.
                          About the first post. Why have we a little leak there, please? Is it because the label won't get deleted until the program terminates? When was is it supposed to be deleted to avoid leaking?

                          And if we want to have a proper code for that example based on Qt standards, we need to firstly have a parent, like a QMainWindow or QWidget or even the QApplication itself, and then set it as the parent to the label. True?

                          mrjjM Offline
                          mrjjM Offline
                          mrjj
                          Lifetime Qt Champion
                          wrote on last edited by
                          #12

                          @qcoderpro said in A little memory leak in a simple Qt program:

                          Thanks.
                          About the first post. Why have we a little leak there, please? Is it because the label won't get deleted until the program terminates? When was is it supposed to be deleted to avoid leaking?

                          When you use new on a Qt type, and do not give it a parent, you must manually delete it.
                          so in fist code, its been newed so it won't be cleanup as such when the program exits. ( well it will but on OS level)

                          And if we want to have a proper code for that example based on Qt standards, we need to firstly have a parent, like a QMainWindow or QWidget or even the QApplication itself, and then set it as the parent to the label. True?

                          True. the parent must exist to assign it but in many cases,
                          the labels are put inside a form or similar so it makes sense.

                          1 Reply Last reply
                          1
                          • Q qcoderpro

                            Thanks.
                            About the first post. Why have we a little leak there, please? Is it because the label won't get deleted until the program terminates? When was is it supposed to be deleted to avoid leaking?

                            And if we want to have a proper code for that example based on Qt standards, we need to firstly have a parent, like a QMainWindow or QWidget or even the QApplication itself, and then set it as the parent to the label. True?

                            JonBJ Offline
                            JonBJ Offline
                            JonB
                            wrote on last edited by JonB
                            #13

                            @qcoderpro said in A little memory leak in a simple Qt program:

                            And if we want to have a proper code for that example based on Qt standards, we need to firstly have a parent, like a QMainWindow or QWidget or even the QApplication itself, and then set it as the parent to the label. True?

                            QLabel (any QWidget) has to have a QWidget *parent, not a QObject *parent. You will not be able to use QApplication * as the parent....

                            Hence if you were to stick with your original create QLabel with no QWidget available to be its parent, to have it deleted you would need to use one of the two approaches: @mrjj's make it a stack variable or @SGaist's do an explicit delete. The same will (presumably, unless a Qt expert tells me otherwise) apply if you introduce, say, a QMainWindow as the top-level window.

                            Q 1 Reply Last reply
                            1
                            • JonBJ JonB

                              @qcoderpro said in A little memory leak in a simple Qt program:

                              And if we want to have a proper code for that example based on Qt standards, we need to firstly have a parent, like a QMainWindow or QWidget or even the QApplication itself, and then set it as the parent to the label. True?

                              QLabel (any QWidget) has to have a QWidget *parent, not a QObject *parent. You will not be able to use QApplication * as the parent....

                              Hence if you were to stick with your original create QLabel with no QWidget available to be its parent, to have it deleted you would need to use one of the two approaches: @mrjj's make it a stack variable or @SGaist's do an explicit delete. The same will (presumably, unless a Qt expert tells me otherwise) apply if you introduce, say, a QMainWindow as the top-level window.

                              Q Offline
                              Q Offline
                              qcoderpro
                              wrote on last edited by qcoderpro
                              #14

                              @JonB

                              (any QWidget) has to have a QWidget *parent

                              Does it mean that every widget's parent must only be a QWidegt or any other widget which has inherited QWidget?

                              1 Reply Last reply
                              0
                              • B Offline
                                B Offline
                                Bonnie
                                wrote on last edited by Bonnie
                                #15

                                @qcoderpro

                                Does it mean that every widget's parent must only be a QWidegt or any other widget which has inherited QWidget?

                                Yes, or nullptr, which means it has no parent. Usually a top-level widget (a window) does not have a parent.
                                If you must create a parentless widget on the heap and hope it be automatically deleted when it is closed, you can use:

                                setAttribute(Qt::WA_DeleteOnClose)
                                
                                Q 1 Reply Last reply
                                2
                                • B Bonnie

                                  @qcoderpro

                                  Does it mean that every widget's parent must only be a QWidegt or any other widget which has inherited QWidget?

                                  Yes, or nullptr, which means it has no parent. Usually a top-level widget (a window) does not have a parent.
                                  If you must create a parentless widget on the heap and hope it be automatically deleted when it is closed, you can use:

                                  setAttribute(Qt::WA_DeleteOnClose)
                                  
                                  Q Offline
                                  Q Offline
                                  qcoderpro
                                  wrote on last edited by
                                  #16

                                  @Bonnie
                                  cool hint! :)

                                  That actually raised this question in my mind. We say widgets built on the heap (using new) must be either explicitly deleted using the "delete" keyword or child of a parent. Assume we've 10 widgets created on the heap. Then they're all children of a top-level widget, for example, a QMainWindow. Actually we should be certain that QMainWindow is deleted, since it comprises many heap widgets, before the program terminates. One solution is the one you said. Another solution is to firstly create the top-level widget on the stack (although its children are created on the heap). Do you know of a third solution?

                                  B JonBJ 2 Replies Last reply
                                  0
                                  • Q qcoderpro

                                    @Bonnie
                                    cool hint! :)

                                    That actually raised this question in my mind. We say widgets built on the heap (using new) must be either explicitly deleted using the "delete" keyword or child of a parent. Assume we've 10 widgets created on the heap. Then they're all children of a top-level widget, for example, a QMainWindow. Actually we should be certain that QMainWindow is deleted, since it comprises many heap widgets, before the program terminates. One solution is the one you said. Another solution is to firstly create the top-level widget on the stack (although its children are created on the heap). Do you know of a third solution?

                                    B Offline
                                    B Offline
                                    Bonnie
                                    wrote on last edited by
                                    #17

                                    @qcoderpro
                                    We usually just create the top-level widget on the stack or delete it manually.
                                    If you do want to create the widget on the heap and do not want to delete it manually, you need Qt to delete it for you.
                                    For example, what the "Qt::WA_DeleteOnClose" attribute do is, as the doc says, "Makes Qt delete this widget when the widget has accepted the close event".
                                    So Qt delete it for you after it is closed.
                                    But if the window is created but never shows, then it won't be deleted (because it never closes).
                                    Another solution I can think of would be using QSharedPointer, it will "delete the pointer it is holding when it goes out of scope".

                                    1 Reply Last reply
                                    1
                                    • Q qcoderpro

                                      @Bonnie
                                      cool hint! :)

                                      That actually raised this question in my mind. We say widgets built on the heap (using new) must be either explicitly deleted using the "delete" keyword or child of a parent. Assume we've 10 widgets created on the heap. Then they're all children of a top-level widget, for example, a QMainWindow. Actually we should be certain that QMainWindow is deleted, since it comprises many heap widgets, before the program terminates. One solution is the one you said. Another solution is to firstly create the top-level widget on the stack (although its children are created on the heap). Do you know of a third solution?

                                      JonBJ Offline
                                      JonBJ Offline
                                      JonB
                                      wrote on last edited by
                                      #18

                                      @qcoderpro
                                      How many different solutions do you want? :)

                                      There are only really two: if you new it you must delete it --- which in the case of setAttribute(Qt::WA_DeleteOnClose) is done for you by the Qt framework when the window is closed --- or if you put it on the stack it gets deleted by the run-time code when it goes out of scope.

                                      In the case of your one QMainWindow it is usual to allocate this on the stack in the method where you call QApplication::exec(). You could new and delete it explicitly if you wish. I have seen debates about whether setAttribute(Qt::WA_DeleteOnClose) on your top-level main window (assuming you new it!) works correctly or not, simplest is to put it on the stack.

                                      Q 1 Reply Last reply
                                      1
                                      • JonBJ JonB

                                        @qcoderpro
                                        How many different solutions do you want? :)

                                        There are only really two: if you new it you must delete it --- which in the case of setAttribute(Qt::WA_DeleteOnClose) is done for you by the Qt framework when the window is closed --- or if you put it on the stack it gets deleted by the run-time code when it goes out of scope.

                                        In the case of your one QMainWindow it is usual to allocate this on the stack in the method where you call QApplication::exec(). You could new and delete it explicitly if you wish. I have seen debates about whether setAttribute(Qt::WA_DeleteOnClose) on your top-level main window (assuming you new it!) works correctly or not, simplest is to put it on the stack.

                                        Q Offline
                                        Q Offline
                                        qcoderpro
                                        wrote on last edited by qcoderpro
                                        #19

                                        @JonB

                                        So the best habit is to create the top level widget on the stack and parent the children, all, to it, regardless of them being created on heap or stack as well. So this way there is almost no class which needs to implement the destructor!

                                        One other thing I didn't understand well I think is the termination time of a top-level widget, actually our program, the time when it goes out of scope and Qt deletes it from the stack. This will be done when we close the program, not? But "setAttribute(Qt::WA_DeleteOnClose)" seemingly works the same way too!

                                        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