c++ - Qt:程序意外结束
问题描述
我在 ubuntu 20.04 和 g++ 的 qtCreator 中使用 qt5.15。我的程序编译并运行良好,直到我关闭主窗口,因为我在问题的标题中得到错误。我读到当指针无效时会发生此错误,我试图在我的程序中找到它,但我找不到。
主文件
#include "MainWindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
主窗口.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;
};
主窗口.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
}
脸.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;
};
人脸.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));
}
颜色.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;
};
颜色.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
,控制台调试显示一堆RTTI symbol not found for class 'QObject'
解决方案
我发现,有一堆问题,首先我曾经双重删除子小部件,比如布局(主小部件的子)和另一个小部件进入布局(布局的子),然后我得到了所有我的析构函数为空,但由于删除未分配的内存位置而导致错误new
。在我的情况下,facelet 的动态矩阵不会为每个 Facelet 分配内存,然后我facelets
从Facelet** facelets
变成 aFacelet*** 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;
}
现在它没有问题或任何问题
推荐阅读
- swift - 使用 swift 代理模式,如何修改私有变量?
- python - SQLAlchemy:具有多对多关系的单表继承
- shopify - 如何在shopify中添加图片上传器?
- firebase - 颤动:在 null 上调用的 getter 文档会显示一段时间
- sql - 从表中的日历中选择工作日
- swift - Swift 框架“未找到模块‘RealityKit’”
- python-3.x - 在多处理嵌套循环和字典中面临问题
- php - 在 Braintree 中创建子商家账户会出现“主商家账户 ID 无效”错误
- java - 是否可以在 Java 中使用 Mockito 模拟语句?
- python - 如何在文件中添加引号