QT(Sugaxxn.exe 中)处有未经处理的异常: 0xC0000005
0x00007FFCF7B42F9A (Qt5Widgetsd.dll) (Sugaxxn.exe 中)处有未经处理的异常: 0xC0000005: 读取位置 0xFFFFFFFFFFFFFFFF 时发生访问冲突,
QT 中main_handle是主窗口传递给子窗口的变量,
主窗口有个sig_showBarMsg(alarm_msg)信号,
供子窗口调用。
子窗口在构造函数时,发送信号给主窗口会报错。
构造结束,进入界面后,再发送sig_showBarMsg是可以的。为什么呢?
崩溃的真正原因有 3 个:
1. 子窗口对象还没构造完成
Qt 的
你在构造函数中间就发信号 = 对象还没 “生出来” 就开始干活 → 非法访问内存。
QObject 必须构造函数完全执行完毕,才算一个合法的对象。
2. 父窗口 / 对象关系还没建立好
你传递的
main_handle(主窗口指针)虽然有值,但:- 子窗口还没完成初始化
- 父子关系没建立
- 事件循环还没启动
信号槽本质是事件循环机制,构造函数里事件循环根本没启动,信号发出去等于发到 “空地址”。
3. 0xC0000005 访问冲突 = 野指针 / 空对象调用
报错信息:
plaintext
读取位置 0xFFFFFFFFFFFFFFFF
这就是典型的:
你调用了一个【还没准备好的 QObject 对象】的槽函数 → 指针非法。
三、为什么构造结束后发信号就没问题?
因为:
- 子窗口对象构造完成
- 事件循环启动(Qt 界面必须靠事件循环)
- 信号槽机制完全就绪
- 主窗口、子窗口指针都安全有效
这时候发信号 = 安全通信。
四、正确写法(
错误写法(你现在的代码)
cpp
运行
// 子窗口构造函数 —— 崩溃!
ChildWindow::ChildWindow(QWidget *main_handle, QWidget *parent)
: ui(new Ui::ChildWindow)
{
ui->setupUi(this);
this->mainWin = main_handle;
// ❌ 构造函数里发信号 = 崩溃
emit mainWin->sig_showBarMsg("初始化消息");
}
正确写法(
方案 :使用 Qt 延迟执行(最推荐、最简单)
让信号等构造完再发:
#include <QTimer>
ChildWindow::ChildWindow(QWidget *main_handle, QWidget *parent)
: ui(new Ui::ChildWindow)
{
ui->setupUi(this);
this->mainWin = main_handle;
//aa1(),//错误。
// ✅ 延迟发送,构造完成后再执行 QTimer::singleShot(0, this, [this]() { emit mainWin->sig_showBarMsg("初始化消息"); }); }0ms不是真的等 0 秒,而是让事件循环下一次空闲时执行,也就是构造完全结束后。
也不能放在子窗口的函数里面:
子窗口构造时调用:
aa1(),错误。
childwindows: aa1()
{
emit mainWin->sig_showBarMsg
}
欢迎讨论,相互学习。
cdtxw@foxmail.com

浙公网安备 33010602011771号