Search code examples
cgraph-algorithmkruskals-algorithm

C: Value of variable changing without re-assignment


I am implementing Kruskal's algorithm.

After I call graph() in the following code, the value of nodes change. I'm not quite sure why -- if anyone could clear this up I would greatly appreciate it. I'm not accessing the value of nodes from within graph, and both nodes & edges, the array being accessed, are allocated outside of the stack!

struct node {
  int parent, rank;
};
typedef struct node node;

struct edge {
  int fromvertex, tovertex;
  float weight;
};
typedef struct edge edge;

node* nodes;
edge* edges;

typedef enum {Unvisited, Visited} vertexstate;

int main (int argc, char const *argv[])
{
  void getcount(int*, int*);
  void graph(int, int);
  void makeset(int);
  int hasspantree(int, int, int);
  void kruskal(int, int);
  int printmcst(int);
  int nodecount, edgecount, i, totalcost=0;
  getcount(&nodecount, &edgecount);
  for (i = 1; i <= nodecount; i++)
    makeset(i);
  printf("%d \t %d\n", nodes[6].parent, nodes[6].rank );
  graph(nodecount, edgecount);
  printf("%d \t %d\n", nodes[6].parent, nodes[6].rank );
  printf("Has a spanning tree?");
  if(hasspantree(1, nodecount, edgecount)) {
    printf("\t Yes.\n");
    kruskal(nodecount, edgecount);
    printf("MCST found:\n\n");
    totalcost = printmcst(nodecount);
    printf("\nCost: %d", totalcost);
  }
  else {
    printf("No.");
    exit(0);
  }
  return 0;
}

void graph(int nodecount, int edgecount)
{
  for (int i = 0; i < edgecount; i++) {
    scanf("%d", &edges[i].fromvertex);
    scanf("%d", &edges[i].tovertex);
    scanf("%f", &edges[i].weight);
  }
}

void getcount(int *nodecount, int *edgecount)
{
  scanf("%d", nodecount);
  scanf("%d", edgecount);
  nodes = malloc(*nodecount * sizeof(node));
  edges = malloc(*edgecount * sizeof(edge));
}

void makeset(int x)
{
  nodes[x].parent = x;
  nodes[x].rank = 0;
}

Solution

  • one obvious error is accessing the nodes array starting at index 1 instead of 0 and this would cause buffer overrun when you access the last element

     for (i = 1; i <= nodecount; i++)  <-- here i should start at 0 and access only up to nodecount-1
        makeset(i);