使用Qt线程和信号的缓冲区溢出

Buffer Overrun using Qt Threads and Signals

本文关键字:缓冲区 溢出 信号 Qt 线程 使用      更新时间:2023-10-16

我不得不将一个项目从QT5降级到QT4,这样做时会出现一个奇怪的缓冲区溢出错误

我创建了一个这样的QThread:

thread = new QThread;
reader = new Reader();
reader->setParams(samplingRate);
reader->moveToThread(thread);
connect(thread, SIGNAL(started()), reader, SLOT(read()));
connect(reader, SIGNAL(finished()), thread, SLOT(quit()));
connect(thread, SIGNAL(finished()), this, SLOT(threadFinished()));
connect(reader, SIGNAL(finished()), reader, SLOT(deleteLater()));
connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
connect(reader, SIGNAL(errorMsg(QString)), this, SLOT(threadErrorMsg(QString)));
thread->start();

在我的线程中,我有以下代码:

try {
     while(condition) {
         ...something
     }
} catch(Exception e) {
     emit errorMsg("Error");
}
emit finished();

我主线程中的Slots看起来是这样的:

void MainWindow::threadFinished() {
    reader = NULL;
    delete thread;
    thread = NULL;
}
void MainWindow::threadErrorMsg(QString message) {
    QMessageBox::critical(this, "Error", ("Error: " + message).toStdString().c_str(), QMessageBox::Ok);
}

所有这些都在QT5中运行良好。错误消息框显示正确,线程已损坏。然而,在QT4(4.8.1)中,当发生错误并发出errorMsg()时,我会得到一个缓冲区溢出错误。如果我不发出errorMsg("Error")并仅通过调用finished()销毁线程,则不会发生缓冲区溢出。有什么想法吗?

更新:如果我不访问threadErrorMsg中的QString,它确实有效。像这样:

void MainWindow::threadErrorMsg(QString message) {
    QMessageBox::critical(this, "Error", "Error", QMessageBox::Ok);
}

我做错了什么?

void MainWindow::threadFinished() {
    reader = NULL;
    delete thread;
    thread = NULL;
}

不建议直接删除插槽中的线程。您应该使用deleteLater函数。

thread->deleteLater();

但是,您已经在连接中设置了要删除的线程

connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));

所以你现在正试图删除它两次!

至于缓冲区溢出,我怀疑在错误发生之前有什么东西损坏了内存。