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. Program.exe has stopped working

Program.exe has stopped working

Scheduled Pinned Locked Moved Solved General and Desktop
17 Posts 3 Posters 5.0k Views
  • 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.
  • SGaistS Offline
    SGaistS Offline
    SGaist
    Lifetime Qt Champion
    wrote on last edited by
    #4

    Likely the delete of the series object. The chart takes ownership of the series so technically you have a double deletion.

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

    cpperC 1 Reply Last reply
    1
    • SGaistS SGaist

      Likely the delete of the series object. The chart takes ownership of the series so technically you have a double deletion.

      cpperC Offline
      cpperC Offline
      cpper
      wrote on last edited by cpper
      #5

      @SGaist Don't think that is the problem, if I'm closing the second opened widget first, everything is ok.
      It also seems that the series are not deleted when the QChartView is destroyed. The QChart however, is destroyed. I've tested by doing qDebug()<<series after loop.exec().

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

        How did you determine that the series wasn't destroyed ?

        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
        1
        • cpperC Offline
          cpperC Offline
          cpper
          wrote on last edited by
          #7

          By doing qDebug()<<series; after loop.exec(); which successfully prints QtCharts::QLineSeries(0x37e7530).
          Placing delete series; before qDebug()<<series; , or doing qDebug()<<chart; results in "program.exe has stopped working"

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

            Having a pointer with an address in doesn't make it valid. Calling delete on a pointer in C++ doesn't result in having it re-initialized. You have a dangling pointer that you are trying to delete.

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

            cpperC 1 Reply Last reply
            2
            • cpperC Offline
              cpperC Offline
              cpper
              wrote on last edited by cpper
              #9

              Try to open 2 or more charts and close them lifo. The instruction "delete series;" doesn't cause any trouble if doing so. If it's about dangling pointers why does this work ?

              Also, the instruction qDebug()<<chart; alone blocks the program.

              1 Reply Last reply
              0
              • SGaistS SGaist

                Having a pointer with an address in doesn't make it valid. Calling delete on a pointer in C++ doesn't result in having it re-initialized. You have a dangling pointer that you are trying to delete.

                cpperC Offline
                cpperC Offline
                cpper
                wrote on last edited by
                #10

                @SGaist I also tried printing a point from the series by doing qDebug()<<series->at(0).x(); and get a valid result.

                kshegunovK 1 Reply Last reply
                0
                • cpperC cpper

                  @SGaist I also tried printing a point from the series by doing qDebug()<<series->at(0).x(); and get a valid result.

                  kshegunovK Offline
                  kshegunovK Offline
                  kshegunov
                  Moderators
                  wrote on last edited by kshegunov
                  #11

                  @cpper
                  Consider this:

                  char * test = new char[4];
                  test[0] = 'A';
                  test[3] = 'C';
                  delete test; //< Now we don't have the memory anymore
                  
                  qDebug() << test[3]; //< Reading an invalid location, yet you'd probably get 'C' and no crash
                  

                  It's the same with objects, until memory is overwritten you have a good chance that your object is still there, so getting a value for:

                  qDebug() << series->at(0).x();
                  

                  just means nothing.

                  What does this print out:

                  void MainWindow::on_pushButton_clicked()
                  {
                      // ... Your code before loop.exec() goes here ...
                  
                      QPointer<QLineSeries> guarded(series);
                      loop.exec();
                  
                      if (!guarded)
                          qDebug() << "Ouch! We have a nasty ownership problem, we want to delete an object we don't own ...";
                      else  {
                          qDebug() << "We are okay, series points to a valid object";
                          delete series;
                      }
                  }

                  Read and abide by the Qt Code of Conduct

                  1 Reply Last reply
                  1
                  • cpperC Offline
                    cpperC Offline
                    cpper
                    wrote on last edited by cpper
                    #12

                    It prints ""We are okay, series points to a valid object".
                    If guarded pointer points to the QChart it prints ""Ouch! We have a nasty ownership problem, we want to delete an object we don't own ...";
                    So this finally confirms that the chart gets deleted but the series not, right ?

                    @SGaist said in Program.exe has stopped working:

                    Having a pointer with an address in doesn't make it valid. Calling delete on a pointer in C++ doesn't result in having it re-initialized. You have a dangling pointer that you are trying to delete.

                    After loop.exec() try qDebug()<<series , and qDebug()<<chart . The first one works but the second crashed the program.

                    Or consider this: QWidget* w=new QWidget(); qDebug()<<w; . This works and prints an address. But QWidget* w=new QWidget(); delete w; qDebug()<<w; crashes the program.
                    I'm not saying that you are wrong, but trying to qDebug() a deleted pointer crashes the program. Since qDebug()<<series worked for me means series wasn't deleted. Or ?

                    kshegunovK 1 Reply Last reply
                    0
                    • cpperC cpper

                      It prints ""We are okay, series points to a valid object".
                      If guarded pointer points to the QChart it prints ""Ouch! We have a nasty ownership problem, we want to delete an object we don't own ...";
                      So this finally confirms that the chart gets deleted but the series not, right ?

                      @SGaist said in Program.exe has stopped working:

                      Having a pointer with an address in doesn't make it valid. Calling delete on a pointer in C++ doesn't result in having it re-initialized. You have a dangling pointer that you are trying to delete.

                      After loop.exec() try qDebug()<<series , and qDebug()<<chart . The first one works but the second crashed the program.

                      Or consider this: QWidget* w=new QWidget(); qDebug()<<w; . This works and prints an address. But QWidget* w=new QWidget(); delete w; qDebug()<<w; crashes the program.
                      I'm not saying that you are wrong, but trying to qDebug() a deleted pointer crashes the program. Since qDebug()<<series worked for me means series wasn't deleted. Or ?

                      kshegunovK Offline
                      kshegunovK Offline
                      kshegunov
                      Moderators
                      wrote on last edited by
                      #13

                      @cpper said in Program.exe has stopped working:

                      So this finally confirms that the chart gets deleted but the series not, right ?

                      No, not necessarily. It means that series is not deleted directly (with delete), it can however be scheduled for deletion (with QObject::deleteLater). And one of the specific things about local event loops is that they don't process those events, they delegate them to the higher-level event loop. So, you may still be getting a double deletion. The other thing that you could try and it will ultimately show whether or not the object is deleted by the chart is if you attach to the QObject::destroyed signal (instead of deleting it explicitly):

                      void MainWindow::on_pushButton_clicked()
                      {
                          // ...
                          loop.exec();
                          // delete series;
                          QObject::connect(series, &QObject::destroyed, [] (QObject *) -> void {
                              qDebug() << "Series is deleted in the parent event loop!"
                          });
                      }
                      

                      Of course, you can also just try substituting delete series with series->deleteLater(), which would solve your problem, if it is in fact a double deletion.

                      Read and abide by the Qt Code of Conduct

                      cpperC 1 Reply Last reply
                      1
                      • kshegunovK kshegunov

                        @cpper said in Program.exe has stopped working:

                        So this finally confirms that the chart gets deleted but the series not, right ?

                        No, not necessarily. It means that series is not deleted directly (with delete), it can however be scheduled for deletion (with QObject::deleteLater). And one of the specific things about local event loops is that they don't process those events, they delegate them to the higher-level event loop. So, you may still be getting a double deletion. The other thing that you could try and it will ultimately show whether or not the object is deleted by the chart is if you attach to the QObject::destroyed signal (instead of deleting it explicitly):

                        void MainWindow::on_pushButton_clicked()
                        {
                            // ...
                            loop.exec();
                            // delete series;
                            QObject::connect(series, &QObject::destroyed, [] (QObject *) -> void {
                                qDebug() << "Series is deleted in the parent event loop!"
                            });
                        }
                        

                        Of course, you can also just try substituting delete series with series->deleteLater(), which would solve your problem, if it is in fact a double deletion.

                        cpperC Offline
                        cpperC Offline
                        cpper
                        wrote on last edited by
                        #14

                        @kshegunov @SGaist

                        The slot is indeed called. So the conclusion of the illusion is that the chart is immediately destroyed after the widget is closed, but the series is later destroyed. This explains everything. Thanks guys for being pacient and making everything clear to me.

                        kshegunovK 1 Reply Last reply
                        0
                        • cpperC cpper

                          @kshegunov @SGaist

                          The slot is indeed called. So the conclusion of the illusion is that the chart is immediately destroyed after the widget is closed, but the series is later destroyed. This explains everything. Thanks guys for being pacient and making everything clear to me.

                          kshegunovK Offline
                          kshegunovK Offline
                          kshegunov
                          Moderators
                          wrote on last edited by
                          #15

                          @cpper
                          Yes, the object's deferred deletion is yet again deferred ...
                          Local event loops are discouraged in principle, and you can see why.

                          Read and abide by the Qt Code of Conduct

                          1 Reply Last reply
                          1
                          • cpperC Offline
                            cpperC Offline
                            cpper
                            wrote on last edited by cpper
                            #16

                            This was the original code:

                                QEventLoop loop;
                                chartView->setAttribute( Qt::WA_DeleteOnClose );
                                connect(chartView,&QChartView::destroyed,&loop,&QEventLoop::quit);
                                chartView->show();
                            
                                loop.exec();
                                delete series;
                            

                            Now that I've learned that deleting the chartView also deletes the chart,series, and axis, I've replaced the code with :

                            chartView->setAttribute( Qt::WA_DeleteOnClose );
                            chartView->show();
                            

                            And it works like a charm now. Of course, the complete version of the program.

                            One last thing I've noticed: If I explicitly delete series, the program does not crash if it automatically wants to delete series (later). But if the program has already automatically deleted series and I try to explicitly delete it afterwards, I get the "program.exe has stopped working". That being said, it seems the automatic deletion(the ownership thing) checks firstly if the pointer is still valid, like you did in the example with the "guarded" pointer.

                            kshegunovK 1 Reply Last reply
                            0
                            • cpperC cpper

                              This was the original code:

                                  QEventLoop loop;
                                  chartView->setAttribute( Qt::WA_DeleteOnClose );
                                  connect(chartView,&QChartView::destroyed,&loop,&QEventLoop::quit);
                                  chartView->show();
                              
                                  loop.exec();
                                  delete series;
                              

                              Now that I've learned that deleting the chartView also deletes the chart,series, and axis, I've replaced the code with :

                              chartView->setAttribute( Qt::WA_DeleteOnClose );
                              chartView->show();
                              

                              And it works like a charm now. Of course, the complete version of the program.

                              One last thing I've noticed: If I explicitly delete series, the program does not crash if it automatically wants to delete series (later). But if the program has already automatically deleted series and I try to explicitly delete it afterwards, I get the "program.exe has stopped working". That being said, it seems the automatic deletion(the ownership thing) checks firstly if the pointer is still valid, like you did in the example with the "guarded" pointer.

                              kshegunovK Offline
                              kshegunovK Offline
                              kshegunov
                              Moderators
                              wrote on last edited by kshegunov
                              #17

                              @cpper said in Program.exe has stopped working:

                              That being said, it seems the automatic deletion(the ownership thing) checks firstly if the pointer is still valid, like you did in the example with the "guarded" pointer.

                              It does, sort of - it removes the pending events for the object, because Qt has to guarantee that multiple calls to QObject::deleteLater don't lead to side effects (as is documented) .

                              Read and abide by the Qt Code of Conduct

                              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