C++ 由于删除而崩溃(尝试处理异常…)

C++ 由于删除而崩溃(尝试处理异常…),c++,qt,exception,memory,crash,C++,Qt,Exception,Memory,Crash,我正在用Qt编写一个程序,我希望它在代码中的某个地方抛出错误时显示一个带有退出|重新启动选项的对话框 我所做的导致了一场车祸,我真的不明白为什么会发生,我希望你能帮助我理解发生了什么 这是我的main.cpp: #include "my_application.hpp" int main(int argc, char *argv[]) { std::cout << std::endl; My_Application app(argc, argv); re

我正在用Qt编写一个程序,我希望它在代码中的某个地方抛出错误时显示一个带有退出|重新启动选项的对话框

我所做的导致了一场车祸,我真的不明白为什么会发生,我希望你能帮助我理解发生了什么

这是我的
main.cpp:

#include "my_application.hpp"

int main(int argc, char *argv[])
{
    std::cout << std::endl;

    My_Application app(argc, argv);

    return app.exec();
}
最后,这里是我的应用程序.cpp:

#ifndef MY_APPLICATION_HPP
#define MY_APPLICATION_HPP

#include <QApplication>

class Window;

class My_Application : public QApplication
{
public:
    My_Application(int& argc, char ** argv);
    virtual ~My_Application();

    virtual bool notify(QObject * receiver, QEvent * event);

private:
    Window *window_;

    void exit();
    void restart();
};

#endif // MY_APPLICATION_HPP
#include "my_application.hpp"
#include "window.hpp"

#include <QMessageBox>

My_Application::My_Application(int& argc, char ** argv) : QApplication(argc, argv)
{
    window_ = new Window;
    window_->setAttribute(Qt::WA_DeleteOnClose, false);
    window_->show();
}

My_Application::~My_Application()
{
    delete window_;
}

bool My_Application::notify(QObject * receiver, QEvent * event)
{
    try
    {
        return QApplication::notify(receiver, event);
    }
    catch(QString error_message)
    {
        window_->setEnabled(false);

        QMessageBox message_box;
        message_box.setWindowTitle("Error");
        message_box.setIcon(QMessageBox::Critical);
        message_box.setText("The program caught an unexpected error:");
        message_box.setInformativeText("What do you want to do? <br>");

        QPushButton *restart_button = message_box.addButton(tr("Restart"), QMessageBox::RejectRole);
        QPushButton *exit_button = message_box.addButton(tr("Exit"), QMessageBox::RejectRole);

        message_box.setDefaultButton(restart_button);

        message_box.exec();

        if ((QPushButton *) message_box.clickedButton() == exit_button)
        {
            exit();
        }
        else if ((QPushButton *) message_box.clickedButton() == restart_button)
        {
            restart();
        }

    }
    return false;
}


void My_Application::exit()
{
    window_->close();
    //delete window_;

    return;
}

void My_Application::restart()
{
    window_->close();
    //delete window_;

    window_ = new Window;
    window_->show();
    return;
}
#包括“my_application.hpp”
#包括“window.hpp”
#包括
My_应用程序::My_应用程序(int&argc,char**argv):QApplication(argc,argv)
{
窗口=新窗口;
窗口->设置属性(Qt::WA_DeleteOnClose,false);
窗口->显示();
}
My_Application::~My_Application()
{
删除窗口;
}
bool My_应用程序::notify(QObject*接收器,QEvent*事件)
{
尝试
{
返回QApplication::notify(接收者、事件);
}
捕获(QString错误消息)
{
窗口->设置启用(假);
QMessageBox消息盒;
message_box.setWindowTitle(“错误”);
message_box.setIcon(QMessageBox::Critical);
message_box.setText(“程序捕获到意外错误:”);
message_box.setInformativeText(“您想做什么?
”); QPushButton*restart\u button=message\u box.addButton(tr(“restart”),QMessageBox::RejectRole); QPushButton*exit_button=message_box.addButton(tr(“exit”),QMessageBox::RejectRole); 消息框。设置默认按钮(重新启动按钮); message_box.exec(); 如果((QPushButton*)消息框。单击按钮()=退出按钮) { 退出(); } 如果((QPushButton*)消息框。单击按钮()=重新启动按钮) { 重启(); } } 返回false; } 作废我的应用程序::退出() { 窗口->关闭(); //删除窗口; 返回; } 作废我的应用程序::重新启动() { 窗口->关闭(); //删除窗口; 窗口=新窗口; 窗口->显示(); 返回; }
请注意,行
window\uu->setAttribute(Qt::WA\u DeleteOnClose,false)表示关闭时不会删除
窗口(我的主窗口)

我上面写的代码可以工作,但据我所知,内存泄漏:我应该取消注释
//delete window
我的应用程序::退出()
我的应用程序::重新启动()
。但是当我这样做的时候,当我点击重启(或者退出,但谁在乎)时,程序崩溃了

(我不确定这是否有用,事实上可能有误导性,但我的调试器告诉我:分段错误发生在
QWidgetPrivate::PaintOnScreen()const
中,它是由函数调用的函数调用的,
my_Application::notify()

当我执行一些
std::cout
s时,我注意到程序在崩溃之前会运行整个
restart()
函数,实际上是整个
notify()
函数

我不知道它为什么会崩溃。提前感谢您的见解

更新:

  • 我注意到,
    我的应用程序::notify()
    经常被调用。例如,在错误对话框打开时,也在重新启动函数执行期间,会多次调用它
  • 崩溃实际上发生在子函数
    QApplication::notify(receiver,event)
    中。鉴于前面的评论,这并不太令人惊讶(接收者可能已被删除)
  • 但是,即使我在执行
    restart()
    时禁止函数
    myu\u Application::notify()
    执行任何操作,它仍然会崩溃(在调用
    myu\u Application::notify()
    很多次之后,比如15次,不是很奇怪吗)

  • 我应该如何进行?也许我应该说(为了让问题稍微相关一点),我的类
    我的应用程序
    也有一个“还原”功能,我在这里复制这个功能不是为了尽量简短。如果我有重启功能,我就不会太麻烦了,但我确实希望有恢复功能。我还应该说,如果我保留注释了“delete window_u2;”的代码,那么问题不仅仅是内存泄漏,有时显然还会崩溃。一定有办法解决这个问题!但我不知道,我真的很感谢你的帮助!提前感谢。

    使用
    窗口->删除后()

    当事件队列中仍有窗口的事件时,您正在删除该窗口;在上面的输出中,它看起来像是在您删除绘画命令后试图传递该命令
    deleteLater()
    将delete命令放入队列,以便在删除之前传递“正常”事件


    同样为了澄清,所有事件都会通过
    QApplication::notify(..)
    -这就是为什么经常调用它,以及为什么它是Qt中异常处理的中心点。

    您是否尝试过使用带断点的gdb?最有可能的情况是,您试图删除仍在使用的指针,从而导致分段错误。我有一种感觉,实际上在重新启动程序时,您应该调用系统命令在新进程中重新启动程序并杀死旧进程,而不是试图恢复出错的进程。问题是我不知道在哪里放置断点,因为程序离开
    notify()
    很好,然后崩溃。至于你的建议,你可能是对的,但1)我不确定我会怎么做2)尽管如此,我不知道错误是从哪里来的,我希望我知道