《QT从基础到进阶·三十九》0xC0000005: 读取位置 0xFFFFFFFFFFFFFFFF 时发生访问冲突或Access violation writing location 0x000000

有时候在正常运行程序时或者正常关闭程序时突然引发如下的崩溃:
0x00007FF7640CF1EB 处(位于 LightLeakageTester.exe 中)引发的异常: 0xC0000005: 读取位置 0xFFFFFFFFFFFFFFFF 时发生访问冲突。

Exception thrown at 0x00007FFBB3BE8886 (Qt5Gui.dll) in LightLeakageTester.exe: 0xC0000005: Access violation writing location 0x0000000000000000

这时候很让人摸不着头脑,因为你并不知道具体在哪里出现的崩溃,下面一个案例是我遇到的一种情况可以进行参考,希望对遇到这类问题的你有所帮助。

在mainWindow中有如下代码:

RIOController* m_RIOController = &RIOController::getInstance();  //创建RIO对象

getInstance内部实现如下:
在这里插入图片描述

RIOController析构函数中有:

LoggingWrapper::getinstance()->debug("Not connected to RIOController.");

debug内部实现为:
在这里插入图片描述

QDockWidget* logdock = new QDockWidget();   //创建悬浮窗对象
m_LogWidget = new QtMessageLogWidget(this);  //new一个log界面对象
LoggingWrapper::getinstance()->setLoggingWidget(m_LogWidget);  //把log界面的指针设置到loggingWrapper中的loggingwidget

QHBoxLayout *layout = new QHBoxLayout();
layout->addWidget(m_LogWidget);    //把log界面放到布局

QGroupBox *groupBox= new QGroupBox();
groupBox->setLayout(layout);      //把布局设置到QGroupBox

logdock->setWidget(groupBox);   //把QGroupBox设置到悬浮窗
addDockWidget(Qt::BottomDockWidgetArea, logdock);  //设置悬浮窗在mainWindow底部停靠

问题复现:
关闭软件,mainWindow先析构,析构完了,其他成员在析构,由于m_RIOController不是new出来的对象,在栈中创建,所以会在mainWindow析构完自动析构m_RIOController,里面打印debug,然后在if里面的那一条报错。这是为啥,m_LogWidget是我new出来的并没有delete,怎么会在析构的时候报空指针异常?

原因:
m_LogWidget继承QWidget,在new QtMessageLogWidget(this)或addDockWidget已经把m_LogWidget的父对象设为mainWindow,在mainWindow析构完后会自动析构对象树上的成员,那么m_LogWidget界面会被析构掉,然后RIOController开始析构(因为在栈上创建放在最后析构,先析构mianWindow和对象树上所有成员),到debug里面loggingWidget已被析构这时候在调用肯定报错。

修改:
RIOController单例中改为new一个对象,然后在mainWindow的析构中手动delete m_RIOController,这样,mainWindow析构的时候会先析构m_RIOController,走m_RIOController析构函数时里面的debug下的loggingWidget还没有被析构掉,这时可以正常调用,后面等到mainWindow析构完在析构对象数上的成员后loggingWidget才被析构。
在这里插入图片描述

在这里插入图片描述
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

梦回阑珊

一毛不嫌多,一分也是爱

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值