我有一个程序可以运行适合某些数据的最小二乘法。此过程在单独的线程中运行,并通过对话框进行控制。这个对话框有一个 QPlainTextEdit 显示拟合更新和最终报告。
该对话框是在 Qt Designer 中创建的,代码在 QtCreator 中运行,我的 Qt 版本是 4.8.1。
我遇到的问题有点不稳定。当我第一次运行该程序时,一切都很好。然后,如果我再次运行它,有时程序会因消息而崩溃
抛出 'std::bad_alloc' 的实例后调用终止 what(): std::bad_alloc 程序意外完成。
我将问题跟踪到对 QPlainTextEdit 的 clear() 方法的调用。这是一些代码。
// Snippets of the class definition
class QLSQDialog : public QDialog, public Ui_QLSQDialog
{
Q_OBJECT
public:
QLSQDialog(QWidget *parent = 0);
(...)
void UpdateDisplay(const QString &msg, int iter, double norm); // Update values of chi, etc on displays
signals:
void Run(); // Signal to run a LSQ procedure
(...)
private slots:
void on_btnRun_clicked();
(...)
private:
void Enables(bool running); // Enable and disable features depending on running state of LSQ fit
(...)
};
// Snippets of the class implementation
QLSQDialog::QLSQDialog(QWidget *parent) : QDialog(parent)
{
setupUi(this); // Set up dialog
(...)
txtInfo->clear(); // txtInfo is a QPlainTextEdit created in Designer
(...)
}
void QLSQDialog::UpdateDisplay(const QString &msg, int iter, double norm)
{
lblChi->setText(QString::number(norm,'f',12));
if (iter >= 0) lblIt->setText(QString::number(iter));
txtInfo->appendPlainText(msg);
}
void QLSQDialog::on_btnRun_clicked()
{
txtInfo->clear(); // Offending line in second run
Enables(true);
emit Run();
}
void QLSQDialog::Enables(bool running)
{
bool Idle = !running;
bool HasReport = !txtInfo->document()->isEmpty();
(...)
btnReport->setEnabled(Idle && HasReport);
}
txtInfo
是 QPlainTextEdit 对象。我在创建对象时调用 atxtInfo->clear()
以显示空文本编辑。当我单击“运行”工具按钮时,其默认插槽会发出一个运行信号,该信号将启动新线程。QPlainTextEdittxtInfo
在这个线程中更新,直到它完成(实际上线程发出一个信号,该信号在主应用程序中被捕获,该主应用程序又调用UpdateDisplay
)。
如果我再次单击运行按钮,则会出现崩溃和错误。如果我替换txtInfo->clear()
, txtInfo->document()->clear()
, bytxtInfo->setPlainText("")
或 bytxtInfo->document()->setPlainText("")
问题是相同的(第二次执行时崩溃)。偶尔但不经常,我可以在崩溃之前运行几次(大约 10 次)。
最后,如果我注释掉该txtInfo->clear()
行,那么我可以尽可能多地运行该例程(在一次测试中,我在运行它大约 80 次后感到疲倦)。
我唯一的(几乎是随机的)猜测是问题与线程的更新有关(它发出一个被捕获的信号,然后只是调用UpdateDisplay
函数)。我这么认为的原因是,如果我注释掉信号并创建一个新按钮来调用UpdateDisplay
一些虚假信息,一切都很好。
违规行之前的AqApp->processEvents()
无效。
我被困在这里。欢迎任何想法。例如,我可以做任何测试来验证调用该clear()
方法是否正常?