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: 96

Filed under:
|
|
|
|

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:

  1. 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.
  2. 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)
  3. But even if I forbid the function My_Application::notify() to do anything while restart() is executed, it still crashes (after having called My_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

Related posts about qt

Related posts about exception