title: C++ while using priority queue Debug assertion failed, Expression: invalid heap
body: <p>Environment:<br>
  - Win7 pro x64<br>
  - VS2010<br>
  - C++<br>
  - Empty Project  </p>
  
  <p>Goal:
   Implementation of Dijkstra's shortest path algo using a priority queue.</p>
  
  <p>Problem:
   When the program runs it gets a Debug assertion failed, Expression: invalid heap error.  If the user inputs the source vertex as 1, everything works fine.  The assertion only occurs when the source vertex is other than 1.  Also, if the assertions are ignored, the code finishes eventually and outputs the proper paths through the graph.  I am guessing the error has something to do with altering the data that pointers in the priority queue point to, but if this is the case, I don't understand why using 1 as the source allows the code to complete successfully.</p>
  
  <p>Thanks for any and all help!</p>
  
  <p>header:</p>
  
  <pre><code>#ifndef _GRAPH_H_
  #define _GRAPH_H_
  #include &lt;map&gt;
  #include &lt;queue&gt;
  #include &lt;vector&gt;
  #include &lt;fstream&gt;
  
  using namespace std;
  
  class Graph
  {
  
  public:
  
      struct Vertex
      {
          int name; // V number
          double dv; // distance
          Vertex* pv; // previous V* from this V
          map&lt;Vertex*, double&gt; neighbors; // map of all neighbors/distances connected to vert
      };
  
      vector&lt;Vertex*&gt; verts; // vector of all V*
  
      void dijkstra(ifstream&amp; stream, int start_vert); // create graph &amp; find shortest paths
      void printPath(Vertex* v); // echo path
  
      class CompareVert // overloaded compare operator for priorty queue data struct, sort queue so V with smallest dist on top
      {
      public:
          bool operator()(const Vertex* v1, const Vertex* v2) const
          {
              return v1-&gt;dv &gt; v2-&gt;dv;
          }
      };
  };
  
  #endif
  </code></pre>
  
  <p>implementation: </p>
  
  <pre><code>#include "Graph.h"
  #include &lt;iostream&gt;
  #include &lt;queue&gt;
  #include &lt;limits&gt; // used for numeric_limits&lt;double&gt;::infinity()
  #include &lt;vector&gt;
  
  using namespace std;
  
  int path_length = 0;
  
  void Graph::printPath(Vertex* v) // print shortest paths
  {
      if (v-&gt;pv != NULL)
      {
          printPath(v-&gt;pv);
          cout &lt;&lt; " -&gt; ";
      }
      cout &lt;&lt; v-&gt;name;
  }
  
  void Graph::dijkstra(ifstream&amp; stream, int start_vert) // create graph &amp; get shortest path
  {
      /////////////////////////////////////////////
      /////////////// create graph ////////////////
      /////////////////////////////////////////////
  
      int total_edges;
      priority_queue&lt;Vertex*, vector&lt;Vertex*&gt;, CompareVert&gt; q;
      double infinity = numeric_limits&lt;double&gt;::infinity();
      int source;
      int dest;
      double dist;
      stream &gt;&gt; total_edges;
      for (int i=0;i&lt;total_edges;i++)
      {
          stream &gt;&gt; source;
          stream &gt;&gt; dest;
          stream &gt;&gt; dist;
          bool source_exists = false;
          bool dest_exists = false;
          Vertex* _source;
          Vertex* _dest;
  
          for (int i=0;i&lt;verts.size();i++)
          {
              if (verts.at(i)-&gt;name == source) // vertex already exists, set to V
              {
                  _source = verts.at(i);
                  source_exists = true;
                  break;
              }
          }
  
          for (int i=0;i&lt;verts.size();i++)
          {
              if (verts.at(i)-&gt;name == dest) // vertex already exists, set to V
              {
                  _dest = verts.at(i);
                  dest_exists = true;
                  break;
              }
          }
  
          if (!source_exists) // create vert
          {
              _source = new Vertex;
              _source-&gt;name = source;
              _source-&gt;dv = infinity;
              _source-&gt;pv = NULL;
              verts.push_back(_source);
          }
  
          if (!dest_exists) // create vert
          {
              _dest = new Vertex;
              _dest-&gt;name = dest;
              _dest-&gt;dv = infinity;
              _dest-&gt;pv = NULL;
              verts.push_back(_dest);
          }
          _source-&gt;neighbors.insert(pair&lt;Vertex*, double&gt;(_dest, dist)); // populate V's adjacency map
      }
  
      for (int i=0;i&lt;verts.size();i++)
      {
          if (verts.at(i)-&gt;name == start_vert) // set source
          {
              verts.at(i)-&gt;dv = 0;
          }       
          q.push(verts.at(i)); // push all vertices to priority queue
      }
  
      /////////////////////////////////////////////
      ////////////////  find paths  ///////////////
      /////////////////////////////////////////////
  
      vector&lt;int&gt; displayed;
      bool print; // flag to call printPath
      while (!q.empty())
      {
          map&lt;Vertex*, double&gt;::iterator it;
          Vertex* temp = q.top(); // get V with smallest dist
          print = true;
          for (it = temp-&gt;neighbors.begin(); it!=temp-&gt;neighbors.end();++it)
          {
              if ((temp-&gt;dv + it-&gt;second) &lt; it-&gt;first-&gt;dv)
              {
                  print = false;
                  it-&gt;first-&gt;dv = (temp-&gt;dv + it-&gt;second);
                  it-&gt;first-&gt;pv = temp;
                  q.push(it-&gt;first);
              }
          }
  
          for (int i=0;i&lt;displayed.size();i++) // if end V of path has already been printed, do not print
          {
              if (displayed.at(i) == temp-&gt;name)
                  print = false;
          }
  
          if (print == true)
          {
              printPath(temp);
              path_length = temp-&gt;dv;
              cout &lt;&lt; " total distance = " &lt;&lt; path_length &lt;&lt;endl &lt;&lt; endl;
              displayed.push_back(temp-&gt;name);
          }
  
          path_length = 0;
          q.pop();
      }
  }
  </code></pre>
  
  <p>driver:</p>
  
  <pre><code>#include "Graph.h"
  #include &lt;stdio.h&gt;
  #include &lt;iostream&gt;
  #include &lt;string&gt;
  #include &lt;fstream&gt;
  #include &lt;list&gt;
  
  using namespace std;
  
  string fname;
  int vname;
  string line;
  
  int main(void)
  {
      cout &lt;&lt; "Please enter the file to read in a graph (graph.txt): ";
      cin &gt;&gt; fname;
      cout &lt;&lt; "Please choose a starting vertex (1 is a good choice): ";
      cin &gt;&gt; vname;
      cout &lt;&lt; endl;
  
      ifstream my_stream (fname);
      Graph my_graph;
      my_graph.dijkstra(my_stream, vname);
      my_stream.close();
  }
  </code></pre>
  
  <p>graph.txt:</p>
  
  <pre><code>12
  1 2 2
  1 4 1
  2 4 3
  2 5 10
  3 1 4
  3 6 5
  4 3 2
  4 5 2
  4 6 8
  4 7 4
  5 7 6
  7 6 1
  </code></pre>