2

メモリを割り当てるクラスがあります。例えば:

class image {

public:
    image(){
        pixelvalue = 0;
    }

    void formatandcopy() {
        pixelvalue = new int [10000*50000];
        if(pixelvalue)
            qDebug()<<"allocation successful"; 
        else 
            qDebug()<<"allocation failed";
    }
private:
    int *pixelvalue;
};

formatandcopy()プログラムを呼び出すと、次のようになります。

Qt has caught an exception thrown from an event handler. Throwing
exceptions from an event handler is not supported in Qt. You must
reimplement QApplication::notify() and catch all exceptions there.

誰かが私がこれを防ぐ方法を知っていて、それが単にメモリ不足であることをユーザーに知らせますか?これを実行すると、表示されませんallocation failed。上記のエラーは、qDebug()が呼び出される前にスローされます。割り当てられたメモリの量が減ると、プログラムは正常に実行されます。newqt関数ではなく演算子を使用するとこのエラーがスローされるため、これは奇妙だと思いました。さらに、私のマシンには十分なメモリが残っています。これは、qtがプログラムを特定のヒープスペースに制限した結果だと思います。最後に、関数を実際に再実装することでこれを修正できる場合、notify誰かがこれを行うための正しい方向に私を向けることができますか?

4

3 に答える 3

3

std :: bad_allocをキャッチして、その関数内の例外を処理できるはずです。例外は標準C++の一部です。

try {
  // ...
} catch (std::bad_alloc &a) {
  // ...
}

それがその範囲を超えた場合(Qtイベント処理に)、QApplication::notify指定どおりに実装する必要があります。

警告の言葉として、悪い割り当ては通常回復可能ではありません。例外は、通常、メモリを大量に消費するアプリケーションを使用しない場合に、(おそらくユーザー入力に基づいて)非常に大量に割り当てることがわかっている場合です。

編集:

明確にするために、アプリケーションの設計でメモリが不足する可能性がある場合、bad_allocsをキャッチして無視しても、何も変更されない可能性があります。プログラムは停止しています。何が起こったかについてのエラーメッセージのみを表示できます。メッセージボックスを作成するためのメモリを割り当てることができないため、これも注意が必要です。

反例は、ユーザーにファイルを要求し、それをすべてメモリに読み込むようなシナリオです。最終的に、彼らはあなたに彼らがメモリを持っていないファイルを与えようとします、そしてあなたは彼らに別のファイルを試すように安全に言うことができます。これらの種類の問題は通常、アプリケーションで分離されており、防御する価値があります。

于 2012-07-10T21:48:51.280 に答える
1

エラーメッセージは、何が起こったのか、何をすべきかを正確に示しています。例外をイベントハンドラー(またはシグナル/スロットメカニズム内の何か)から伝播することはできません。例外を適切に処理するには、例外を内部QApplication::notify()でキャッチする必要があります。これ:

bool MyApplication::notify( QObject* receiver, QEvent* event )
{
    try {
        return QApplication::notify( receiver, event );
    } catch ( std::exception& e ) {
        cout << "Arrrgggghhhh" << endl;
        return false;
    }
}

また、Qtではなく、使用できるヒープスペースの量を決定するのはOSです。

于 2012-07-10T21:53:12.033 に答える
0

pixelvalueを実行して整合性をチェックする必要はありません。失敗したif(pixelvalue)場合new、例外がスローされ、ポインタがどこにも割り当てられないためpixelvalue存在しないため、存在しないポインタの整合性をチェックすることは無意味です。NULLポインタではないか確認したい場合に使用します。

于 2012-07-10T21:57:19.753 に答える