0

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_;
};
Nelarius
  • 181
  • 2
  • 10

0 Answers0