Qt: Программа неожиданно завершилась

Я работаю с qt5.15 в qtCreator в ubuntu 20.04 и g ++. Моя программа компилируется и работает нормально, пока я не закрою главное окно, потому что в заголовке вопроса появляется ошибка. Я прочитал, что эта ошибка возникает, когда есть недействительный указатель, я пытался найти его в своей программе, но не смог.

main.cpp

      #include "MainWindow.h"

#include <QApplication>

    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
        MainWindow w;
        w.show();
        return a.exec();
    }

MainWindow.h

      #pragma once

#include "Facelet.h"
#include "Face.h"

#include <QMainWindow>
#include <QWidget>
#include <QSpacerItem>

class MainWindow : public QMainWindow
{
    Q_OBJECT

    using type = Face;

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

protected:

    virtual void resizeEvent(QResizeEvent*) override;

private:

    void __init_spacers();

    QWidget* wid;
    type* object;
    QGridLayout* layout;
    QSpacerItem* spacer;

};

MainWindow.cpp

      #include "MainWindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    object = new type();
    layout = new QGridLayout();
    wid = new QWidget();
    __init_spacers();
    layout->setContentsMargins(0,0,0,0);
    layout->addWidget(object, 1, 1);
    wid->setLayout(layout);
    setCentralWidget(wid);
}

MainWindow::~MainWindow()
{
    delete spacer;
    delete object;
    delete layout;
    delete wid;
}

//protected

void MainWindow::resizeEvent(QResizeEvent*) {
    int side = (size().width() < size().height()) ? size().width() : size().height();
    object->resize(side, side);
}

//private

void MainWindow::__init_spacers() {
    spacer = new QSpacerItem(0,0, QSizePolicy::Expanding, QSizePolicy::Expanding);
    layout->addItem(spacer, 0, 1);//top
    layout->addItem(spacer, 1, 0);//left
    layout->addItem(spacer, 2, 1);//bootom
    layout->addItem(spacer, 1, 2);//right
}

Face.h

      #pragma once

#include "Facelet.h"
#include <QGridLayout>
#include <QLabel>

class Face : public QWidget {

    Q_OBJECT

public:

    explicit Face(QWidget* parent = nullptr);
    ~Face();

    std::string get_pattern();

protected:

    virtual void resizeEvent(QResizeEvent *event = nullptr) override;

private:

    void __init_widget();
    void __init_layout();
    void __init_facelets();
    void __update_facelets(int side);
    void __delete_facelets();

    Facelet** facelets;
    QGridLayout* layout;

    constexpr static unsigned int SIDE = 248;
    constexpr static unsigned int SPACE = 10;

};

Face.cpp

      #include "Face.h"

Face::Face(QWidget* parent) : QWidget(parent) {
    __init_facelets();
    __update_facelets(75);
    __init_layout();
    __init_widget();
}

Face::~Face() {
    __delete_facelets();
    delete layout;
}

std::string Face::get_pattern() {
    std::string result;
    for(int i = 0; i < 3; ++i) {
        for(int j = 0; j < 3; ++j) {
            result.push_back( char(Colors::list[facelets[i][j].id()].second) );
        }
    }
    return result;
}

//protyected

void Face::resizeEvent(QResizeEvent *event) {
    int side = (size().width() > size().height()) ? size().width() : size().height();
    int facelet_side = (side-8)/3;
    __update_facelets(facelet_side);
}


//private

void Face::__init_widget() {
    this->resize(SIDE, SIDE);
    this->setMinimumSize(SIDE, SIDE);
    this->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
    this->setAttribute(Qt::WA_StyledBackground);
    this->setStyleSheet("background-color: black;");
    this->setLayout(layout);
}

void Face::__init_layout() {
    layout = new QGridLayout();
    layout->setSpacing(2);
    layout->setContentsMargins(2, 2, 2, 2);
    for(int i = 0; i < 3; ++i) {
        for(int j = 0; j < 3; ++j) {
            layout->addWidget(&facelets[i][j], i, j);
        }
    }
}

void Face::__init_facelets() {
    facelets = new Facelet*[3];
    for(int i = 0; i < 3; ++i) {
        facelets[i] = new Facelet[3];
    }
}

void Face::__update_facelets(int side) {
    for(int i = 0; i < 3;++ i) {
        for(int j = 0; j < 3; ++j) {
            facelets[i][j].setFixedSize(side, side);
        }
    }
}

void Face::__delete_facelets() {
    for(int i = 0; i < 3; ++i) {
        delete[] facelets[i];
    }
    delete[] facelets;
}

Facelette.h

#pragma once

#include "Colors.h"

#include <QPushButton>
#include <QPainter>

class Facelet : public QPushButton {

    Q_OBJECT

public:

    using id_type = Colors::Id;

    explicit Facelet(QWidget* parent = nullptr);
    explicit Facelet(Colors::Id color, QWidget* parent = nullptr);
    virtual ~Facelet();

    void reset();
    void set_color(Colors::Id);
    id_type id();

protected:
    virtual void paintEvent(QPaintEvent *e = nullptr) override;

public slots:

    void __change_color();

private:
    
    int _Id;

};

Facelet.cpp

      #include "Facelet.h"
#include <QStyleOption>

Facelet::Facelet(QWidget* parent) : QPushButton(parent) {
    reset();
    connect(this, SIGNAL(clicked()), SLOT(__change_color()));
}

Facelet::Facelet(Colors::Id id_, QWidget* parent) : QPushButton(parent) {
    set_color(id_);
    connect(this, SIGNAL(clicked()), SLOT(__change_color()));
}

Facelet::~Facelet() {}

void Facelet::reset() {
    _Id = -1;
    this->setStyleSheet("background-color:lightGray;");
}

void Facelet::set_color(Colors::Id _id) {
    _Id = _id;
    setStyleSheet(QString("background-color:")+Colors::list[_Id].first+";");
}

Facelet::id_type Facelet::id() {
    return Facelet::id_type(_Id);
}

//protected

void Facelet::paintEvent(QPaintEvent *) {
    QStyleOption opt;
    opt.init(this);
    QPainter p(this);
    style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);
}

//private slots

void Facelet::__change_color() {
    _Id = (_Id >= 5) ? 0 : (_Id+1);
    set_color(Colors::Id(_Id));
}

Colors.h

      #pragma once

#include "Rubix/Rubix.h"

#include <array>
#include <utility>
#include <QColor>


struct Colors {

    using value_type = typename std::pair<QString, rbx::RColor>;
    using array_type = typename std::array<value_type, 6>;
    enum Id { Yellow, Red, Green, Orange, Blue, White };
    static array_type list;

};

Colors.cpp

      #include "Colors.h"

Colors::array_type Colors::list = {
    Colors::value_type("yellow", rbx::YELLOW),
    Colors::value_type("rgb(255, 20, 20)", rbx::RED),
    Colors::value_type("rgb(35, 255, 35)", rbx::GREEN),
    Colors::value_type("rgb(255, 130, 20)", rbx::ORANGE),
    Colors::value_type("blue", rbx::BLUE),
    Colors::value_type("white", rbx::WHITE),
};

когда я закрываю окно, я получаю следующую ошибку

      21:07:22: Starting /home/kubuntu/Desktop/projects/x64/RubbixSolver/Debug/GUI/build-GUI-Desktop_Qt_5_15_2_GCC_64bit-Profile/GUI ...
21:07:46: The program has unexpectedly finished.
21:07:46: The process was ended forcefully.
21:07:46: /home/kubuntu/Desktop/projects/x64/RubbixSolver/Debug/GUI/build-GUI-Desktop_Qt_5_15_2_GCC_64bit-Profile/GUI crashed.

Если я запускаю отладку, когда закрываю главное окно, в нем говорится о проблеме в Face ::~Face(), появляется небольшое окно со следующим сообщением: «Нижний модуль остановлен, потому что он получил сигнал от операционной системы. . Signal name : SIGSEGV Signal meaning : Segmentation fault, отладка Conosle отображает набор RTTI symbol not found for class 'QObject'

1 ответ

Я понял, что возникла куча проблем, прежде всего я использовал двойное удаление дочерних виджетов, таких как макет (дочерний элемент основного виджета) и другой виджет в макете (дочерний элемент макета), затем я получил все мои деструкторы пусты, но я получил ошибку, вызванную удалением области памяти, не выделенной с помощью new. В моем случае динамическая матрица Facelet не выделяет память для каждого Facelet, затем я повернул facelets из Facelet** facelets в Facelet*** facelets и изменил init_facelets() к

      void Face::init_facelets() {
    facelets = new Facelet**[3];
    for(int i = 0; i < 3; ++i) {
        facelets[i] = new Facelet*[3];
        for(int j = 0; j < 3; ++j) {
            facelets[i][j] = new Facelet();
        }
    }
}

Когда программа завершается, Face :: ~ Face () освобождает все места, соответствующие facelets[i] [j], затем мне пришлось освободить остальную часть матрицы, поэтому теперь Face :: ~ Face () выглядит как

      Face::~Face() {
    for(int i = 0; i < 3; ++i) {
        delete[] facelets[i];
    }
    delete[] facelets;
}

Теперь он работает без проблем или проблем

Другие вопросы по тегам