我有一个程序运行适合某些数据的最小二乘法。此过程在单独的线程中运行,并从对话框中控制。此对话框有一个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对象。当对象出现时,我调用txtInfo->clear()
创建以显示空文本编辑。当我点击“运行”工具按钮时,其默认插槽会发出一个启动新线程的运行信号。 txtInfo
QPlainTextEdit在此线程中更新,直到完成为止(实际上线程发出的信号在主应用程序中捕获,而后者又调用UpdateDisplay
)。
如果我第二次点击运行按钮,那么我会收到崩溃和错误。如果我将txtInfo->clear()
,txtInfo->document()->clear()
替换为txtInfo->setPlainText("")
或txtInfo->document()->setPlainText("")
,则问题是相同的(第二次执行时崩溃)。偶尔,但不经常,我可以在崩溃之前运行几次(大约10次)。
最后,如果我注释掉txtInfo->clear()
行,那么我可以像我尝试的那样运行例程(在一次测试中,我跑了大约80次后感到疲倦)。
我唯一(几乎是随机的)猜测是问题与线程的更新有关(它发出的信号被捕获,反过来只调用UpdateDisplay
函数)。我之所以这么认为,如果我将这些信号注释掉,只是创建一个新按钮,用一些虚假信息来调用UpdateDisplay
,一切都很好。
违规行之前的qApp->processEvents()
无效。
我被困在这里。欢迎任何想法。例如,我可以做任何测试来验证调用clear()
方法是否正常?
答案 0 :(得分:0)
我终于将此问题跟踪到我的代码中令人讨厌的内存泄漏。我“修复”了代码,但我仍然有点困惑为什么问题发生了。
基本上,我在某处创建一个大vector<double>
并将其地址传递给一个调用vector<double> *
变量的函数。问题是原始向量在函数完成之前不再存在。经典的愚蠢错误。可能QPlainTextEdit
文档正在vector<double>
曾经存在的区域中分配空间:预期的不稳定行为。但我不希望发生崩溃。
向量是“只读”。使用它的函数,只读取值并将计算存储在其他地方。现在假设纯文本在先前由vector<double>
解决的内存中创建了一些内容。在这种情况下,当我QPlainTextEdit::clear()
纯文本文档时,向量先前指向的值发生变化,我希望计算是无意义的。当函数访问现在已故的vector<double>
指针时,我也会接受崩溃。但是当我清除文本时,我不希望程序崩溃,毕竟这是一个有效的指针。
无论如何,如果有人有,我很想知道崩溃发生的原因。但否则,一旦泄漏修复,问题就消失了。当然,知道原因绝对没有理由不修复泄漏。