1

大量のメモリを割り当て、一致するドキュメントを見つけようとするクエリ プロセッサを作成しています。一致するものを見つけるたびに、ドキュメントを記述する 2 つの変数を保持する構造を作成し、それを優先キューに追加します。これを何回行うかを知る方法がないため、new を使用して構造体を動的に作成してみました。構造体をプライオリティ キューからポップすると、キュー (STL プライオリティ キューの実装) がオブジェクトのデストラクタを呼び出すことになっています。私の構造体コードにはデストラクタがないため、その場合はデフォルトのデストラクタが呼び出されると想定しています。

ただし、初めて DOC 構造体を作成しようとすると、次のエラーが発生します。

QueryProcessor.exe の 0x7c812afb で未処理の例外: Microsoft C++ 例外: メモリ位置 0x0012f5dc の std::bad_alloc..

何が起こっているのかわかりません - ヒープがいっぱいになるほど多くのメモリを使い果たしましたか? ありそうにありません。そして、そのポインターを以前に使用したことがあるかのようではありません。

まず第一に、エラーの原因となっているのは何ですか?次に、次のコードは複数回機能しますか? 作成された構造体ごとに個別のポインターが必要ですか、それとも同じ一時ポインターを再利用して、キューが各構造体へのポインターを保持すると想定できますか?

これが私のコードです:

struct DOC{
    int docid;
    double rank;

    public:
        DOC()
        {
            docid = 0;
            rank = 0.0;
        }

        DOC(int num, double ranking)
        {
            docid = num;
            rank = ranking;

        }

        bool operator>( const DOC & d ) const {
           return rank > d.rank;
        }

        bool operator<( const DOC & d ) const {
           return rank < d.rank;
        }
};


//a lot of processing goes on here

        priority_queue<DOC, std::vector<DOC>, std::greater<DOC>> q;

//when a matching document is found, I do this:

rank = calculateRanking(table, num);

    //if the heap is not full, create a DOC struct with the docid and rank and add it to the heap
    if(q.size() < 20)
    {
        doc = new DOC(num, rank);
        q.push(*doc);
        doc = NULL;
    }

    //if the heap is full, but the new rank is greater than the 
    //smallest element in the min heap, remove the current smallest element
    //and add the new one to the heap
    else if(rank > q.top().rank)
    {
        q.pop();

        cout << "pushing doc on to queue" << endl;
        doc = new DOC(num, rank);
        q.push(*doc);
    }

どうもありがとう、bsg。

4

4 に答える 4

4

ヒープ上に次の構造を作成するのはなぜですか:

doc = new DOC(num, rank);
q.push(*doc);

これは、最初DOCにヒープ上に を作成し、次にオブジェクトのコピーをキューに格納し、続いて動的に作成された をリークしますDOC

以下で十分であり、リークしません。

q.push(DOC(num, rank));
于 2010-04-04T17:50:47.063 に答える
0

std :: bad_allocは、メモリが不足しているときにスローされます。

q.pop()を実行するときに、ポップしようとしているポインタを解放する必要があります。そうしないと、リークが発生します。たくさんの要素がある場合、これが問題になる可能性があります。

Doc *p = q.front();
delete p;
q.pop();

他の人が述べているように、Doc *ではなくDocを保持するようにキューを宣言すると、メモリを自分で管理する必要がなくなり、コンテナが自動的に処理します。

于 2010-04-04T17:40:21.157 に答える
0

例外について:クラスには、エラーの原因の読み取り可能な説明を含む文字列にを返すbad_allocメンバー関数があります。what()const char *

編集:動的に割り当てられたオブジェクトの保存を検討している場合は、オブジェクトへの参照ではなく、ポインターを保存してください。

于 2010-04-04T17:45:10.557 に答える
0

メモリリークがあります。STLコンテナの挿入メソッドは、渡したタイプのコピーを格納するため、ヒープにドキュメントを割り当てる必要はありません。

それ以外の

doc = new DOC(...)
q.push(*doc);
doc = NULL;

どちらかを行う

doc(...);
q.push(doc);

または

doc = new DOC(...);
q.push(*doc);
delete doc;
doc = NULL;
于 2010-04-04T17:46:33.113 に答える