I am trying to generate a spanning tree of a graph by using a randomized version of Prim's algorithm. However, my program crashes during the spanning tree generation phase, and closer examination has revealed three different errors.
1) A SIGTRAP is received at usedEdges.push_back(*i);
(in the code below), where usedEdges
is of type std::vector<Edge>
.
2) A SIGTRAP is received within the code for the graph, at a very similar line: edges_[edge.From()].push_back(edge);
, where edges_
is of type std::vector<std::list<Edge> >
3) And a few times I have received a SEGFAULT when the I try print the edge's info to the terminal, although I haven't been able to reproduce it very many times.
If I've understood correctly, the fact that I'm receiving a SIGTRAP means that Windows is triggering some kind of error due to memory corruption? If so, where is my memory getting corrupted?
The code for generating the spanning tree is below. The maze_
member is a graph, which internally stores nodes & edges in a vector & adjacency list.
typedef std::set<int> NodeSet;
typedef std::list<Edge> EdgeList;
typedef std::vector<EdgeList> AdjacencyList;
AdjacencyList adjacencyList;
std::vector<Edge> usedEdges;
NodeSet usedNodes;
//generate grid nodes
for (int i = 0; i < height_; i++)
{
for (int j = 0; j < width_; j++)
{
Node node(maze_.GetNextFreeNodeIndex());
//nodes.push_back(node);
maze_.AddNode(node);
adjacencyList.push_back(std::list<Edge>());
}
}
//generate grid edges
for (int i = 0; i < height_; i++)
{
for (int j = 0; j < width_; j++)
{
int k = i * width_ + j;
if (i > 0)
{
Edge edge(k, k - width_);
adjacencyList[k].push_back(edge);
}
if (i < height_ - 1)
{
Edge edge(k, k + width_);
adjacencyList[k].push_back(edge);
}
if (j > 0)
{
Edge edge(k, k - 1);
adjacencyList[k].push_back(edge);
}
if (j < width_ - 1)
{
Edge edge(k, k + 1);
adjacencyList[k].push_back(edge);
}
}
}
///Randomized Prim's algorithm
//mark first used node, and add all edges leading from this node to the used edge list.
usedNodes.insert(0);
EdgeList edgeList = adjacencyList[0];
for (EdgeList::iterator i = edgeList.begin(); i != edgeList.end(); i++)
{
usedEdges.push_back(*i);
}
while (!usedEdges.empty())
{
int id = LC::rand() * usedEdges.size() - 0.5;
Edge edge = usedEdges[id];
if (usedNodes.find(edge.To()) == usedNodes.end())
{
maze_.AddEdge(edge);
usedNodes.insert(edge.To());
edgeList = adjacencyList[edge.To()];
for (EdgeList::iterator i = edgeList.begin(); i != edgeList.end(); i++)
{
usedEdges.push_back(*i);
}
}
else
{
usedEdges.erase(usedEdges.begin() + id - 1);
}
}
What I've tried so far: rebuilt the project, tried setting actual breakpoints into the code to watch variables but so far haven't seen anything out of the ordinary. Then again I'm not really sure what I should be looking for...
EDIT
The Edge class declaration is
class Edge
{
public:
//Edge(const Edge& edge);
Edge(int from, int to, float cost);
Edge(int from, int to);
Edge();
virtual ~Edge();
friend std::ostream& operator<<(std::ostream& os, const Edge& edge);
int From() const;
void SetFrom(int index);
int To() const;
void SetTo(int index);
float Cost() const;
void SetCost(float cost);
bool operator==(const Edge& rhs);
bool operator!=(const Edge& rhs);
protected:
int from_;
int to_;
float cost_;
};