3

STLpriority_queueを使用すると、使用しようとするとすぐに「無効なヒープ」というエラーが表示されますpop()。値をキューにプッシュできtop()ます。キューの は、期待どおりであり、アクセス可能です。pop()、再ヒープに行くと、問題があるようです。

テンプレート化されたクラスへのポインタをキューに保存しています。私は比較をオーバーロードしています:

template <class type>
class vertexPriorityCompare
{
public:
   bool operator()(Vertex<type>* leftVertex, Vertex<type>* rightVertex) const
   {
      if(leftVertex->getDistanceFromSource() < 0 && rightVertex->getDistanceFromSource() < 0)
      {
         return false;
      }
      else if(leftVertex->getDistanceFromSource() < 0)
      {
         return true;
      }
      else if(rightVertex->getDistanceFromSource() < 0)
      {
         return false;
      }
      else
      {
         return leftVertex->getDistanceFromSource() > rightVertex->getDistanceFromSource();
      }
   }
};

priority_queueクラスのプライベート メンバーです。

priority_queue< Vertex<type>*, vector< Vertex<type>* >, vertexPriorityCompare<type> > Q;

負の距離は無限大と見なされ、常に他のものよりも大きいため、過負荷はそのように機能します。無限を表すために、距離は -1 に初期化されます。キューは、最小であるが負でないものを一番上に保持する必要があります。

オーバーロードでポインターを逆参照していますが、そこで行っていることは許容されますか? そして、オーバーロードする必要がある別の演算子はありますか?

コードを添付しますが、添付すると、人々を怖がらせてしまうようです。もっと見るようにリクエストしてください。別のメッセージに添付します。

ポインターへのポインターの配列を動的に宣言します。これらはプッシュされるものです。priority_queue参照によってストアを想定しているためです。したがって、ループで宣言されたポインターをキューに入れるだけでは、そのポインターは範囲外になります。これらのポインターは適切な を指しVertex<type>、関数全体に存在します。

Visual Studio 2008 デバッガーは、「stdthrow.cpp」の 24 行目に移動します。

4

5 に答える 5

3

オブジェクトがキューにある間にオブジェクトの値が変化しない場合、比較関数は問題ないように見えます。getDistanceFromSource()それは保証されていますか?getDistanceFromSource()または、オブジェクトがキューに入っている間、またはキューが最初にいっぱいになっている間に、オブジェクトに変更が加えられている可能性がありますか?

于 2009-01-23T23:30:44.777 に答える
3

それはおそらくあなたの比較関数です。テストするには、ポインターを比較するだけの単純なバージョンに置き換えます。

bool operator()(...)
{
  return leftVertex<rightVertex;
}

問題が発生しなくなった場合、問題は比較関数が無効だったことです。コンパレーターは「strict-weak order」を定義する必要があります。私はそうではないことを示すのに十分な男ではありませんが、きっとそれだけです。

于 2009-01-23T22:45:10.237 に答える
0

コールスタックがないと、問題の原因を特定するのが少し難しくなりますが、 をVertex<...>正しく割り当てていないかVertex<...>、スタックから解放しようとしているか、Vertex<...>*を有効な値に初期化していません。

于 2009-01-23T22:27:01.503 に答える
0

このビットは私を怖がらせます:

ポインターへのポインターの配列を動的に宣言します。これらはプッシュされるものです。これは、priority_queue が参照によって格納されると想定しているためです。ループで宣言されたポインターをキューに入れるだけでは、そのポインターは範囲外になります。これらのポインターは適切な頂点を指し、関数全体に存在します。

キューにどのようにデータを入力しているかは明確ではありません。Vertex オブジェクトを作成する必要があり、それらはメモリに残り、キューにある間ずっと同じ距離を返す必要があります。

キューは参照によって保存されず、コピーが保存されますが、この場合、入れているのはポインターであるため、割り当てた元のオブジェクトを引き続き指すポインターをコピーします。

さらに先に進むには、短い完全な例が必要になると思います。

于 2009-01-24T00:05:41.773 に答える
0

この関数はどこから呼び出していますか?

私の推測では、無効なヒープは、「この関数の呼び出し元」のコードから関数に渡すポインターです。または、ベクトルから頂点を取り出しているときに範囲外に出ている可能性があります。

その機能に問題はありません。

スタック トレースを提供してください

于 2009-01-23T22:26:40.740 に答える