Skip to main content
 首页 » 编程设计

c++之由于删除而崩溃(尝试处理异常...)

2025年12月25日40grandyang

我正在用 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() 函数。

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

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

  • 我应该如何进行?也许我应该说(使问题更相关)我的类 My_Application 也有一个“恢复”功能,我没有在这里复制它以保持简短。如果我只有那个重启功能,我不会太费心,但我确实想要那个恢复功能。我还应该说,如果我保留带有“删除窗口_”注释的代码,问题不仅是内存泄漏,它有时仍然明显崩溃。肯定有办法解决这个问题!但我一无所知,我真的很感激一些帮助!提前致谢。

    请您参考如下方法:

    使用window_->deleteLater() .

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

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