一部のデータに対して最小二乗法を実行するプログラムがあります。このプロシージャは別のスレッドで実行され、ダイアログ ボックスから制御されます。このダイアログ ボックスには、フィッティングの更新と最終レポートを表示する 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()
、空のテキスト編集を表示します。「実行」ツール ボタンをクリックすると、そのデフォルト スロットが新しいスレッドを開始する実行シグナルを発します。QPlainTextEdit は、txtInfo
終了するまでこのスレッドで更新されます (実際、スレッドは、メイン アプリケーションでキャッチされるシグナルを発し、次に を呼び出しますUpdateDisplay
)。
もう一度実行ボタンをクリックすると、クラッシュとエラーが発生します。txtInfo->clear()
、txtInfo->document()->clear()
、 、txtInfo->setPlainText("")
または byを置き換えるとtxtInfo->document()->setPlainText("")
、問題は同じです (2 回目の実行でクラッシュします)。頻繁ではありませんが、時折、クラッシュする前に数回 (10 回程度) 実行できます。
最後に、行をコメント アウトすると、txtInfo->clear()
実行した回数だけルーチンを実行できます (あるテストでは、約 80 回実行した後に疲れました)。
私の唯一の(ほぼランダムな)推測は、問題がスレッドからの更新に何らかの形で関連していることです(キャッチされたシグナルを発し、UpdateDisplay
関数を呼び出すだけです)。私がそう思う理由は、シグナルをコメントアウトして、UpdateDisplay
偽の情報で呼び出すための新しいボタンを作成すれば、すべて問題ないからです。
問題のある行の前のAqApp->processEvents()
は効果がありません。
私はここで立ち往生しています。どんなアイデアでも大歓迎です。たとえば、clear()
メソッドの呼び出しに問題がないことを確認するために実行できるテストはありますか?