Qt : crash due to delete (trying to handle exceptions...)
        Posted  
        
            by 
                Seub
            
        on Stack Overflow
        
        See other posts from Stack Overflow
        
            or by Seub
        
        
        
        Published on 2012-10-06T23:41:45Z
        Indexed on 
            2012/10/07
            3:38 UTC
        
        
        Read the original article
        Hit count: 163
        
I am writing a program with Qt, and I would like it to show a dialog box with a Exit | Restart choice whenever an error is thrown somewhere in the code.
What I did causes a crash and I really can't figure out why it happens, I was hoping you could help me understanding what's going on.
Here's my main.cpp:
#include "my_application.hpp"
int main(int argc, char *argv[])
{
    std::cout << std::endl;
    My_Application app(argc, argv);
    return app.exec();
}
And here's 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
Finally, here's 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;
}
Note that the line window_->setAttribute(Qt::WA_DeleteOnClose, false); means that window_ (my main window) won't be deleted when it is closed.
The code I've written above works, but as far as I understand, there's a memory leak: I should uncomment the line //delete window_; in My_Application::exit() and My_Application::restart(). But when I do that, the program crashes when I click restart (or exit but who cares).
(I'm not sure this is useful, in fact it might be misleading, but here's what my debugger tells me: a segmentation fault occurs in QWidgetPrivate::PaintOnScreen() const which is called by a function called by a function... called by My_Application::notify())
When I do some std::couts, I notice that the program runs through the entire restart() function and in fact through the entire notify() function before it crashes.
I have no idea why it crashes. Thanks in advance for your insights!
Update:
- I've noticed that My_Application::notify()is called very often. For example, it is called a bunch of times while the error dialog box is open, also during the execution of the restart function.
- The crash actually occurs in the subfunction QApplication::notify(receiver, event). This is not too surprising in light of the previous remark (the receiver has probably been deleted)
- But even if I forbid the function My_Application::notify()to do anything whilerestart()is executed, it still crashes (after having calledMy_Application::notify()a bunch of times, like 15 times, isn't that weird)?
How should I proceed? Maybe I should say (to make the question slightly more relevant) that my class My_Application also has a "restore" function, which I've not copied here to try to keep things short. If I just had that restart feature I wouldn't bother too much, but I do want to have that restore feature. I should also say that if I keep the code with the "delete window_" commented, the problem is not only a memory leak, it still crashes sometimes apparently. There must surely be a way to fix this! But I'm clueless, I'd really appreciate some help! Thanks in advance.
© Stack Overflow or respective owner