为什么我的Qt应用程序会无缘无故崩溃?

6

我正在编写一个基于sqlite数据库的中等大小的存储数据应用程序。我创建了一个对话框来添加数据到数据库中。在保存数据之前,它将检查一些条件,以确保输入的数据是有效的。这是一个简单的过程,并且很容易发现错误。我确定没有任何错误会在任何时候导致应用程序崩溃。此外,应用程序编译没有错误。有时它可以正常工作,但大多数情况下会崩溃并关闭。

  1. my first question is why does this kind of things happen. (sometimes it works well, sometimes it crashes in the same condition).

  2. how to find faults in this kind of situation. simply what I do is, I use to change the logic and change the code, thinking that it will change the binary and correct the errors.

    ex:-

    if(query.exec()){
         //codes here.
     }
    

    I will replace this code with

    bool ok=query.exec();
      if(ok){
           //code here....
     }
    

请在这种情况下帮助我,任何建议都将非常感激。我将添加导致应用程序崩溃的newMember.hnewMember.cpp文件(这是我的新成员对话框类)。如果需要更多数据,请告诉我,我会添加它们。

错误报告中,在错误签名中提到了ModName:qtgui4.dll,Offset:000c14e6

newMember.h

       #ifndef NEWMEMBER_H
       #define NEWMEMBER_H

       #include "ui_newmember.h"


       class newMember : public QDialog, private Ui::newMember
       {
           Q_OBJECT

       private:
           QString path_1;
           QPixmap pic;

       public:
           newMember(QString str, QWidget *parent );


       public slots:
           void browse();
           void save_2();

      };

      #endif // NEWMEMBER_H

newMember.cpp

        #include "newmember.h"
        #include<QtGui>
        #include<QtSql/QSqlDatabase>
        #include <QSqlQuery>
        #include <QSqlError>

        newMember::newMember(QString str, QWidget *parent)
        {
              setupUi(this);
           lineEdit_7->setText(str);
           radioButton->setChecked(true); ;

           connect(pushButton,SIGNAL(clicked()),this,SLOT(browse()));
           connect(pushButton_2,SIGNAL(clicked()),this,SLOT(save_2()));
        }


        void newMember::browse(){
             path_1=QFileDialog::getOpenFileName(this,"choose an image for the new house", QString::null,"Image Files (*.jpg *.bmp)");
             pic.load(path_1);
             pic=pic.scaled(284,213,Qt::KeepAspectRatio, Qt::SmoothTransformation);
             label_14->setPixmap(pic);
        }

        QString input1(QString str){
             if(str=="")
                 return "-NA-";
              else
                return str;
        }


       void newMember::save_2(){
             QByteArray array;
             QBuffer buf(&array);
             buf.open( QIODevice::WriteOnly);
             pic.save(&buf,"jpg");

             QString mof;
             if(radioButton->isChecked())mof="male";
             if(radioButton_2->isChecked())mof="female";

             QString isgm="false";
             if(checkBox->isChecked())isgm="true";


            QSqlDatabase db=QSqlDatabase::addDatabase("QSQLITE");
            db.setDatabaseName("data");
            db.open();

            QSqlQuery query;
            query.exec("create table members(aname text, homeno text, namein text, fname text, onames text, nic text, sex text, bday text,gm text,occupation text,contactno text,qulification text,note text, img BLOB) ");

             if(lineEdit_8->text()==""){
             QMessageBox::about(this,"error","you should enter a name to identify this member \n within the specific house");
             return;
             }

             query.prepare("select aname from members where homeno=? and aname=?   ");
             query.bindValue(0,lineEdit_7->text());
             query.bindValue(1,lineEdit_8->text());
             query.exec();
             if(query.next()){
             QMessageBox::about(this, "error", "the name you entered to identify this member \n  is already available, please enter another one") ;
             return;
            }

              if(isgm=="true"){
                  query.prepare("select aname from members where homeno=? and gm=?");
                  query.bindValue(0,lineEdit_7->text());
                  query.bindValue(1,"true");
                  query.exec();
                      if(query.next()){
                          QMessageBox::about(this, "error", "there is a gruha mulikaya set already");
                         return;
                        }
                }


                 query.prepare("insert into members(aname, homeno , namein , fname , onames , nic , sex , bday ,gm ,occupation ,contactno ,qulification ,note ,img) VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?)     ");
                 query.bindValue(0,lineEdit_8->text());
                 query.bindValue(1,input1(lineEdit_7->text()));
                 query.bindValue(2,input1(lineEdit->text()));
                 query.bindValue(3,input1(lineEdit_2->text()));
                 query.bindValue(4,input1(lineEdit_3->text()));
                 query.bindValue(5,input1(lineEdit_4->text()));
                 query.bindValue(6,mof);
                 query.bindValue(7,dateEdit->date().toString("yyyy-MM-dd") );
                 query.bindValue(8,isgm);
                 query.bindValue(9,input1(lineEdit_5->text()));
                 query.bindValue(10,input1(lineEdit_6->text()));
                 query.bindValue(11,input1(textEdit->toPlainText()));
                 query.bindValue(12,input1(textEdit_2->toPlainText()));
                 query.bindValue(13,array);


                bool ok=query.exec();
                if(!ok){
                   QSqlError error;
                   error=query.lastError();
                   QMessageBox::about(this,"error",error.text()   );
                 }
                else{
                    QMessageBox::about(this,"message","data added successfully");
                    newMember::close();
                 }

              }

4
在调试器中运行应用程序,它会告诉你它在哪里崩溃。 - Nikos C.
我对调试Qt应用程序一无所知,但我会尝试并给出结果。谢谢。 - danial weaber
在应用程序输出中,@NikosC. 它告诉 程序意外终止. 在此之前有4行如下:QSqlDatabasePrivate::addDatabase: 重复的连接名 'qt_sql_default_connection',旧连接已被删除。 - danial weaber
在调试器中很抱歉它没有给出任何错误,它按预期工作。在上面的评论中它没有处于调试器状态,我只是从QtCreater运行它。在调试器中运行时它不会崩溃。@NikosC. - danial weaber
1
针对“重复连接”的问题,您应该将打开数据库的代码移动到构造函数中,以便它只执行一次(有关详细信息,请参见此答案)。 - alexisdm
@alexisdm 谢谢,我已经修复了。但是我的问题仍然存在... - danial weaber
1个回答

4
  1. 尝试在调试器下运行您的应用程序。它将显示您的应用程序在代码中崩溃的位置。在您的情况下,很可能是段错误。
  2. 为什么不检查返回值?

请看我的评论,那是我的调试器输出。在代码中没有重要的检查返回值的点,不是吗?什么是段错误,请帮忙。 - danial weaber
1
Segfault等同于分段错误和访问冲突。当试图访问处理器无法寻址的内存时,会发生这种错误。例如:引用空指针。 - user355167
抱歉,在调试器中它没有给出任何错误,它按预期工作。在上面的评论中它不是在调试器中运行的,我只是从QtCreater中运行它。当在调试器中运行时,它不会崩溃。 - danial weaber
thanks. I accept your answer - danial weaber

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接