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. Why did I get a 'Debug Assertion Failed' in this QGridLayout project?
Qt 6.11 is out! See what's new in the release blog

Why did I get a 'Debug Assertion Failed' in this QGridLayout project?

Scheduled Pinned Locked Moved Solved General and Desktop
8 Posts 2 Posters 2.9k Views 2 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.
  • D Offline
    D Offline
    DragonautX
    wrote on last edited by DragonautX
    #1

    I was trying out QGridLayout, and I wanted to see if I could place a grid layout within another grid layout. I made three pushbuttons, and placed 2 of them in a smallGrid. I added the smallGrid to the bigGrid, along with the last pushbutton I initialized. The program ran, but on exit, I got a window with an error that included this:

    |||||
    Microsoft Vistual C++ Runtime Library
    Debug Assertion Failed!
    ...
    Expression: _CrtlsValidHeapPointer(block)
    |||||

    Why did I get this error? The program still ran. Did I forget to add something when I made my QGridLayout instances?

    #include <QtWidgets>
    #include <QPushButton>
    
    int main(int argc, char *argv[]) {
        QApplication app(argc, argv);
        QWidget window;
        window.resize(320, 340);
        window.show();
    
        QPushButton a,b,c;
        a.setText("A");
        b.setText("B");
        c.setText("C");
        a.show();
        b.show();
        c.show();
    
        QGridLayout smallGrid;
        smallGrid.addWidget(&a,0,0);
        smallGrid.addWidget(&b,1,0);
    
        QGridLayout bigGrid;
        bigGrid.addLayout(&smallGrid,0,0);
        bigGrid.addWidget(&c,0,1);
    
        window.setLayout(&bigGrid);
    
        return app.exec();
    
    }
    
    1 Reply Last reply
    0
    • mrjjM Offline
      mrjjM Offline
      mrjj
      Lifetime Qt Champion
      wrote on last edited by mrjj
      #2

      :::Pure Guessing:::

      Hi

      smallGrid.addWidget(&a,0,0); This owns the widget. The layout will delete the Widget.

      QPushButton a,b,c; // this will be deleted when running out of scope.

      So a,b,c might be deleted twice. From layout and then from scope.

      You can fix this by newing the buttons or by using a widget and not main for the code.

      1 Reply Last reply
      2
      • D Offline
        D Offline
        DragonautX
        wrote on last edited by DragonautX
        #3

        Oh, ok. I didn't know widgets were deleted after addWidget. I tried placing all my code in a subclass of QWidget in a "header.h", then I put TestWidget widget; window.setLayout(&(widget.bigGrid)); in my main.cpp. It didn't work, still got the debug error. Was that what you meant by "using a widget"? Here's my class definition for TestWidget that I used. Also, what did you mean by "newing the buttons"? QPushButton doesn't seem to have a "renew" function with it.

        class TestWidget: public QWidget {
            Q_OBJECT
        public:
            TestWidget(QWidget *parent = 0 ): QWidget(parent) {
                setup();
            }
        
            QPushButton a,b,c;
            QGridLayout smallGrid;
            QGridLayout bigGrid;
        
            void setup() {
                a.setText("Test");
                smallGrid.addWidget(&a,0,0);
                smallGrid.addWidget(&b,1,0);
                bigGrid.addLayout(&smallGrid,0,0);
                bigGrid.addWidget(&c,0,1);
            }
        };
        
        1 Reply Last reply
        0
        • mrjjM Offline
          mrjjM Offline
          mrjj
          Lifetime Qt Champion
          wrote on last edited by
          #4

          Hi
          Yes moving to widget seems much cleaner :) Good work.

          • Also, what did you mean by "newing the buttons"

          Sorry. badly told.
          What I mean is
          QPushButton *a = new QPushButton ();
          When you new it,
          it means that it would NOT be deleted by scope, only the layout / parent/owner.

          If you are not aware of Qt parent child ownership system, you best read up on it to avoid huge "ohhhh" experiences.
          http://doc.qt.io/qt-5/objecttrees.html

          Basically it means when you give it parent
          QPushButton *a = new QPushButton (this); // this is parent
          or add to layout
          That object now owns it and will delete it for you.

          1 Reply Last reply
          1
          • D Offline
            D Offline
            DragonautX
            wrote on last edited by DragonautX
            #5

            Oh ok, I'll look more into the link. It works now, both in main and in TestWidget class. Allocating on the stack has worked for me until this case, so I'll start allocating on the heap with "new". Thanks!

            mrjjM 1 Reply Last reply
            0
            • D DragonautX

              Oh ok, I'll look more into the link. It works now, both in main and in TestWidget class. Allocating on the stack has worked for me until this case, so I'll start allocating on the heap with "new". Thanks!

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

              @DragonautX
              There is nothing wrong with using the stack, ( at all)
              but one must understand the Owner system as not to crash.
              So often "new" the widgets to avoid deletion conflicts.
              But there are many cases where stack is pretty fine and issue-less.

              Like showing a dialog

              void Ask() {
              MyDialog Dia;
              Dia.exec(); // blocking
              ...
              }

              1 Reply Last reply
              1
              • D Offline
                D Offline
                DragonautX
                wrote on last edited by DragonautX
                #7

                Oh ok, so most of the time I can choose between either stack or heap. Looking at your link, in this case I guess the order of the widget initializations is important, but using "new" and the heap instead of the stack allows for constructors/destructors to be called in any order, allowing my project to run without errors.

                mrjjM 1 Reply Last reply
                0
                • D DragonautX

                  Oh ok, so most of the time I can choose between either stack or heap. Looking at your link, in this case I guess the order of the widget initializations is important, but using "new" and the heap instead of the stack allows for constructors/destructors to be called in any order, allowing my project to run without errors.

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

                  @DragonautX
                  Yes, both stack and heap work
                  but as you have seen , the auto delete system does require you to think
                  slightly more about it when using the stack.

                  1 Reply Last reply
                  1

                  • Login

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