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. Segmentation Fault after assigning QSqlQueryModel from function return in switch statement
QtWS25 Last Chance

Segmentation Fault after assigning QSqlQueryModel from function return in switch statement

Scheduled Pinned Locked Moved Unsolved General and Desktop
c++sqlqsqlqueryqsqlquerymodelsigsegv
14 Posts 6 Posters 1.6k 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.
  • A Offline
    A Offline
    achoy011
    wrote on last edited by
    #1

    Hello, my group and I have been running into an issue where, at random, our application crashes with a segmentation fault. According to the debugger, this occurs when we try to assign a QSqlQueryModel from a function return.

    Here is the function with the offending statement (mainwindow.cpp):

    void MainWindow::on_filterPushButton_clicked()
    {
        filterType = getFilterType();
    
        qDebug() << "Filter dropdown selected index: " << filterType << Qt::endl;
    
        model->clear();
        delete model;
    
        switch(filterType)
        {
            case 0: ;//Genre
            case 1: {   //Leading Actor
                        TableFilter filterLA(new SortLeadActor, movieName);
                        model = filterLA.filter(movieName); //We believe this is where the issue is occuring
                    }
            case 2: ;//SA
            case 3: ;//Dir
            case 4: ;//Release Year
            case 5: ;//IMBD Score
            case 6: ;//Content Rating
        };
    
        ui->MovieTableView->setModel(model);
        ui->MovieTableView->resizeColumnsToContents();
        ui->stackedWidget->setCurrentIndex(1);
    }
    

    The filter function leads to an appliedSort function (which is in a different class):

    QSqlQueryModel * SortLeadActor::appliedSort(QString title)
    {
            model = new QSqlQueryModel();
            qry = new QSqlQuery();
    
            qry->prepare("SELECT Actor_1 FROM movie_metadata WHERE (Movie_Title) = (:movieTitle)");
            qry->bindValue(":movieTitle", title);
    
            //qDebug() << title << Qt::endl;
    
            if(!(qry->exec()))
            {
                qDebug() << "Query exec failed SortLeadActor::appliedSort find movie title" << Qt::endl;
            }
    
            qry->first();
            leadActor = qry->value(0).toString();
            qDebug() << leadActor << Qt::endl;
    
            qry->prepare("SELECT Movie_Title, Director_Name, Actor_1, "
                         "Actor_2, Actor_3, Genres, Content_Rating, "
                         "Title_Year FROM movie_metadata WHERE (Actor_1) = (:leadingActor)");
            qry->bindValue(":leadingActor", leadActor);
    
            if(!(qry->exec()))
            {
                qDebug() << "Query exec failed SortLeadActor::appliedSort find movie title" << Qt::endl;
            }
    
            //Assign query to model
            model->setQuery(std::move(*qry));
            delete qry;
    
            return model;
    }
    

    Basically the model is supposed to be set to the query that is filled in above function.

    Also, here is the result from the debugger:
    alt text

    We all get the same issue, but for some of my group members, this issue does not occur as frequently as other group members. We believe it has something to do with passing the QSqlQueryModel but beyond that we have no clue what's happening.

    1 Reply Last reply
    0
    • M Offline
      M Offline
      mchinand
      wrote on last edited by
      #2
      This post is deleted!
      1 Reply Last reply
      0
      • SGaistS Offline
        SGaistS Offline
        SGaist
        Lifetime Qt Champion
        wrote on last edited by
        #3

        Hi and welcome to devnet,

        You delete your model object but do not reset the pointer value hence if filterType is not 0 or 1, model will point to invalid memory.

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

        R 1 Reply Last reply
        2
        • SGaistS SGaist

          Hi and welcome to devnet,

          You delete your model object but do not reset the pointer value hence if filterType is not 0 or 1, model will point to invalid memory.

          R Offline
          R Offline
          RyanSolanki
          wrote on last edited by
          #4

          @SGaist Hello, I am also part of the poster's group. We are testing this code in a controlled environment where we are isolating the value of filterType to only be 1. The program executes the code in case 1 of the switch statement but then crashes shortly after and never executes the code after the switch. It seems like the program is crashing inside the switch, but still executes all code in case 1.

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

            Wait... why are you allocating your QSqlQuery object on the heap ? There's no reason for that.

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

            R 1 Reply Last reply
            1
            • SGaistS SGaist

              Wait... why are you allocating your QSqlQuery object on the heap ? There's no reason for that.

              R Offline
              R Offline
              RyanSolanki
              wrote on last edited by
              #6

              @SGaist What would you suggest we do to fix that? Sorry we are relatively new to Qt and are still learning

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

                Just allocate it on the stack like all the examples show.

                When you read a method signature that uses const references, it's usually not a good idea to create an object on the heap, only to de reference it to pass it to that method.

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

                R 1 Reply Last reply
                0
                • SGaistS SGaist

                  Just allocate it on the stack like all the examples show.

                  When you read a method signature that uses const references, it's usually not a good idea to create an object on the heap, only to de reference it to pass it to that method.

                  R Offline
                  R Offline
                  RyanSolanki
                  wrote on last edited by
                  #8

                  @SGaist So create the QSqlQuery as a private member of the class rather than in the appliedSort() method?

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

                    No, just create it on the stack in the method, there's no need to use new, nor std::move, nor delete.

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

                    R 1 Reply Last reply
                    1
                    • SGaistS SGaist

                      No, just create it on the stack in the method, there's no need to use new, nor std::move, nor delete.

                      R Offline
                      R Offline
                      RyanSolanki
                      wrote on last edited by
                      #10

                      @SGaist Could that be what is causing the segmentation fault?

                      1 Reply Last reply
                      0
                      • D Offline
                        D Offline
                        DeShark
                        wrote on last edited by
                        #11

                        It looks like the model has already been deleted when the MainWindow's destructor tries to delete it again and that causes a segfault for what should be obvious reasons.

                        From the stack trace the SortLeadActor's destructor is called, and then the MainWindow destructor is called. Are you calling delete on the model that you're returning to MainWindow from appliedSort during ~SortLeadActor?

                        Pl45m4P R 2 Replies Last reply
                        2
                        • D DeShark

                          It looks like the model has already been deleted when the MainWindow's destructor tries to delete it again and that causes a segfault for what should be obvious reasons.

                          From the stack trace the SortLeadActor's destructor is called, and then the MainWindow destructor is called. Are you calling delete on the model that you're returning to MainWindow from appliedSort during ~SortLeadActor?

                          Pl45m4P Offline
                          Pl45m4P Offline
                          Pl45m4
                          wrote on last edited by
                          #12

                          @DeShark

                          Yeah, that would also explain why they are facing the segfault not frequently... If you don't press that button which is connected to the slot where they delete the model, the crash probably won't occur.

                          Anyway, follow @SGaist 's instructions according to the query and in addition, don't try to double delete the pointer.


                          If debugging is the process of removing software bugs, then programming must be the process of putting them in.

                          ~E. W. Dijkstra

                          1 Reply Last reply
                          0
                          • D DeShark

                            It looks like the model has already been deleted when the MainWindow's destructor tries to delete it again and that causes a segfault for what should be obvious reasons.

                            From the stack trace the SortLeadActor's destructor is called, and then the MainWindow destructor is called. Are you calling delete on the model that you're returning to MainWindow from appliedSort during ~SortLeadActor?

                            R Offline
                            R Offline
                            RyanSolanki
                            wrote on last edited by
                            #13

                            @DeShark Thank you! The double delete was the issue and I have now fixed it

                            1 Reply Last reply
                            0
                            • D Offline
                              D Offline
                              DeShark
                              wrote on last edited by
                              #14

                              @RyanSolanki Please mark as solved if you are happy the issue is resolved. Also consider reading up further about Qt's memory management model (maybe it would make sense to pass a parent during the QSqlQueryModel's construction to avoid all that manual memory management or else perhaps smart pointers if there is no clear parent to assign ownership to).

                              Furthermore, SGaist's point about passing a pointer to a function whose signature expects a const reference cannot be understated. If the function expects a pointer, give it a pointer. If it expects a const reference, give it an object created on the stack! https://doc.qt.io/qt-5/qsqlquerymodel.html#details
                              The documentation is good; use it! It is unclear to me why you are using functions such as "clear" for the model. The setQuery() function already clears the model. Why mess around with new and delete several times when you can just pass in a new query to modify the existing model? Futhermore, why bother clear()-ing the model immediately before you delete it? The destructor is called during the delete, which itself frees up any resources, per the documentation.

                              There are deeper problems of comprehension going on here!

                              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