关于QT在打开子窗口时程序崩溃的其中一个原因分析

其实这个问题当时是纠结了我很长的一段时间,这段时间里面,我一直在网上面找相关的资料但是却没有有用的信息。

但是在后面的一个机缘巧合之下,我通过函数执行顺序来Debug,慢慢的发现问题出现在什么地方了。现在来总结一下这个问题吧。

其实我现在的经验觉得,对于QT里面(由于QT是基于C++的),不少的程序崩溃都可以往指针上面去靠拢。因为指针的指向错误或者指向了错误地区导致内存访问出错进而导致程序崩溃是经常出现的一种问题。现在我来说说我的问题。

我的主界面上面有一个按钮,按钮添加的槽就是在点击按钮以后,新创建一个对象,并且把这个对象给show出来。

但是这个时候经常就是会出现Program Unexpected Stop/Crash

我就很痛苦,通过程序执行顺序逻辑来查看里面的问题,一开始感觉没有什么问题,但是后面就开始发现不对劲了。

void MainWindow::enter_eigth_number()
{
    numWin = new enumber();
    numWin->show();
}

看这个代码,就是打开子窗口的槽函数,恩,现在还很好;

注释了numWin->show()发现崩溃现象仍然存在,定位在numWin产生对象时发生错误;

去看看numWin的函数

enumber::enumber(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::enumber)
{
    ui->setupUi(this);
    setWindowTitle("小小八数码");
    init_pic();
    connect(ui->close,SIGNAL(clicked(bool)),this,SLOT(close()));
    connect(ui->start,SIGNAL(clicked(bool)),this,SLOT(start()));
    connect(ui->load,SIGNAL(clicked(bool)),this,SLOT(loadp()));
}

怎么感觉还很好呢??

再看看init_pic();

void enumber::init_pic()
{
    QImage *ice;
    ice= new QImage(":/image/0");
    imgstack.push_back(*ice);
    ice= new QImage(":/image/1");
    imgstack.push_back(*ice);
    ice= new QImage(":/image/2");
    imgstack.push_back(*ice);
    ice= new QImage(":/image/3");
    imgstack.push_back(*ice);
    ice= new QImage(":/image/4");
    imgstack.push_back(*ice);
    ice= new QImage(":/image/5");
    imgstack.push_back(*ice);
    ice= new QImage(":/image/6");
    imgstack.push_back(*ice);
    ice= new QImage(":/image/7");
    imgstack.push_back(*ice);
    ice= new QImage(":/image/8");
    imgstack.push_back(*ice);

    loadp(open[0]);
}

恩,还没有什么问题啊?TAT


看看loadp()

void enumber::loadp(node *n)
{
    int width = ui->num00->width();
    int height = ui->num00->height();
    ui->num00->setPixmap(QPixmap::fromImage(imgstack[n->disk[0][0]]).scaled(width,height,Qt::IgnoreAspectRatio,Qt::SmoothTransformation));
    ui->num01->setPixmap(QPixmap::fromImage(imgstack[n->disk[0][1]]).scaled(width,height,Qt::IgnoreAspectRatio,Qt::SmoothTransformation));
    ui->num02->setPixmap(QPixmap::fromImage(imgstack[n->disk[0][2]]).scaled(width,height,Qt::IgnoreAspectRatio,Qt::SmoothTransformation));
    ui->num10->setPixmap(QPixmap::fromImage(imgstack[n->disk[1][0]]).scaled(width,height,Qt::IgnoreAspectRatio,Qt::SmoothTransformation));
    ui->num11->setPixmap(QPixmap::fromImage(imgstack[n->disk[1][1]]).scaled(width,height,Qt::IgnoreAspectRatio,Qt::SmoothTransformation));
    ui->num12->setPixmap(QPixmap::fromImage(imgstack[n->disk[1][2]]).scaled(width,height,Qt::IgnoreAspectRatio,Qt::SmoothTransformation));
    ui->num20->setPixmap(QPixmap::fromImage(imgstack[n->disk[2][0]]).scaled(width,height,Qt::IgnoreAspectRatio,Qt::SmoothTransformation));
    ui->num21->setPixmap(QPixmap::fromImage(imgstack[n->disk[2][1]]).scaled(width,height,Qt::IgnoreAspectRatio,Qt::SmoothTransformation));
    ui->num22->setPixmap(QPixmap::fromImage(imgstack[n->disk[2][2]]).scaled(width,height,Qt::IgnoreAspectRatio,Qt::SmoothTransformation));
}

哦豁!!!!!

你们发现了没有??

一开始的构造里面,调用了init_pic();

但是在init_pic()里面调用了loadp;

调用党的loadp()里面还调用了imstack这个没有初始化的东西,在当初写的时候在想到了后续初始化的情况,傻乎乎的忘记了在初始化时指针为空,可能出现越界访问的情况!!!

在构造中吧init_pic注释,OK!

  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
Qt 中,QMainWindow 可以使用 QMdiArea 控件来管理多个窗口。如果需要安全释放 QMdiArea 控件的窗口并清理窗口的 QWidget 内存,可以按照以下步骤进行操作: 1. 遍历 QMdiArea 控件的窗口并删除它们 可以使用 `QMdiArea::subWindowList()` 方法来获取 QMdiArea 控件的所有窗口,然后调用 `QMdiSubWindow::close()` 方法来关闭每个窗口。例如: ```cpp foreach(QMdiSubWindow *subWindow, mdiArea->subWindowList()) { subWindow->close(); } ``` 2. 遍历 QMdiArea 控件的窗口并删除它们的 QWidget 控件 在删除窗口之前,需要先删除窗口的 QWidget 控件。可以使用 `QWidget::findChildren()` 方法来获取每个窗口的所有 QWidget 控件,然后使用 `QLayout::removeWidget()` 方法将每个控件从窗口的布局中移除,并调用 `delete` 运算符来释放内存。例如: ```cpp foreach(QMdiSubWindow *subWindow, mdiArea->subWindowList()) { QList<QWidget *> widgets = subWindow->widget()->findChildren<QWidget *>(); foreach(QWidget *widget, widgets) { QLayout *layout = widget->layout(); if (layout) { layout->removeWidget(widget); } delete widget; } } ``` 3. 删除 QMdiArea 控件的窗口 最后,可以使用步骤 1 中的代码来删除 QMdiArea 控件的窗口并释放内存。例如: ```cpp foreach(QMdiSubWindow *subWindow, mdiArea->subWindowList()) { subWindow->close(); } ``` 注意:在删除窗口控件,一定要小心并仔细考虑,否则可能会导致程序崩溃。建议在删除窗口控件之前,先确保它们没有任何正在运行的操作。同,在使用手动释放 QWidget 内存,一定要注意内存泄漏问题。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值