删除导致崩溃(尝试处理异常......)

时间:2012-10-06 23:41:46

标签: c++ qt exception memory crash

我正在用Qt编写程序,我希望它显示一个带有Exit |的对话框无论何时在代码中的某处抛出错误,都要重新启动选择。

我做了什么导致了崩溃,我真的无法弄清楚为什么会发生这种情况,我希望你能帮我理解发生了什么。

这是我的main.cpp:

#include "my_application.hpp"

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

    My_Application app(argc, argv);

    return app.exec();
}

这里是my_application:hpp

#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

最后,这是my_application.cpp

#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;
}

请注意,行window_->setAttribute(Qt::WA_DeleteOnClose, false);表示window_(我的主窗口)在关闭时不会被删除。

我上面写的代码有效,但据我所知,存在内存泄漏:我应取消注释//delete window_;My_Application::exit()中的行My_Application::restart()。但是当我这样做时,程序会在我点击重启(或退出但关心谁)时崩溃。

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

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

我不知道它崩溃的原因。提前感谢您的见解!

更新

  1. 我注意到My_Application::notify()经常被调用。例如,在错误对话框打开时,它会被多次调用,在执行重启功能期间也是
  2. 崩溃实际发生在子功能QApplication::notify(receiver, event)中。鉴于之前的评论(接收器可能已被删除),这并不太令人惊讶。
  3. 但即使我在执行My_Application::notify()时禁止函数restart()执行任何操作,它仍然会崩溃(在调用My_Application::notify()一堆次数之后,如15次,isn'那很奇怪)?
  4. 我该怎么办?也许我应该说(为了使问题稍微更相关)我的班级My_Application也有一个“恢复”功能,我没有在这里复制以试图保持简短。如果我只是有重启功能,我不会太烦,但我确实想要恢复功能。我还应该说,如果我保持代码中的“删除窗口_”注释,问题不仅是内存泄漏,它有时显然会崩溃。肯定有办法解决这个问题!但我很无能,我真的很感激一些帮助!提前谢谢。

1 个答案:

答案 0 :(得分:0)

使用window_->deleteLater()

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

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