[英]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()
函数运行。
我不知道为什么会崩溃。 预先感谢您的见解!
更新:
My_Application::notify()
经常被调用。 例如,在打开错误对话框以及执行重新启动功能的过程中 ,它被多次调用 。 QApplication::notify(receiver, event)
。 鉴于前面的评论,这并不奇怪(接收方可能已删除) 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.