繁体   English   中英

因删除而崩溃(正在尝试处理异常…)

[英]Crash due to delete (trying to handle exceptions…)

我正在用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发生分段错误,该QWidgetPrivate::PaintOnScreen() const由函数调用的函数调用...由My_Application::notify()调用)

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

我不知道为什么会崩溃。 预先感谢您的见解!

更新:

  1. 我注意到My_Application::notify()经常被调用。 例如,在打开错误对话框以及执行重新启动功能的过程中 ,它被多次调用
  2. 崩溃实际上发生在子函数QApplication::notify(receiver, event) 鉴于前面的评论,这并不奇怪(接收方可能已删除)
  3. 但是即使我禁止函数My_Application::notify()在执行restart()执行任何操作,它仍然会崩溃(在多次调用My_Application::notify()之后My_Application::notify()例如15次),这并不奇怪)?

我应该如何进行? 也许我应该说(使这个问题更有意义),我的类My_Application也具有“恢复”功能,这里没有复制该功能以使内容简短。 如果我只有重启功能,那我就不会太在意,但是我确实希望拥有恢复功能。 我还应该说,如果保留带有“ delete window_”注释的代码,则问题不仅是内存泄漏,而且有时仍然会崩溃。 肯定有解决此问题的方法! 但是我一无所知,我真的很感谢您的帮助! 提前致谢。

使用window_->deleteLater()

当事件队列中仍有事件时,您将删除该窗口; 在上面的输出中,您似乎删除了绘画命令,试图将其发送出去。 deleteLater()将删除命令放入队列,因此“正常”事件在删除之前传递。

同样为了澄清起见,所有事件都通过QApplication::notify(..)传递-这就是为什么如此频繁地调用它,以及为什么它是Qt中异常处理的中心点的原因。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM