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 对象】的槽函数 → 指针非法。
 

 

三、为什么构造结束后发信号就没问题?

 
因为:
 
  1. 子窗口对象构造完成
  2. 事件循环启动(Qt 界面必须靠事件循环)
  3. 信号槽机制完全就绪
  4. 主窗口、子窗口指针都安全有效
 
这时候发信号 = 安全通信。
 

 

四、正确写法( 

 

错误写法(你现在的代码)

 
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

}
posted @ 2026-05-19 15:56  txwtech  阅读(5)  评论(0)    收藏  举报