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