【问题标题】:C: Value of variable changing without re-assignmentC:变量的值改变而不重新赋值
【发布时间】:2014-11-06 03:16:02
【问题描述】:

我正在实现 Kruskal 算法。

在下面的代码中调用 graph() 后,节点的值发生了变化。我不太清楚为什么——如果有人能澄清这一点,我将不胜感激。我没有从图中访问节点的值,并且正在访问的数组的节点和边都分配在堆栈之外!

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;
}

【问题讨论】:

  • 你在makeset做什么?
  • @unxnut 在 makeset 中,我制作了所有节点的单例集。我已经编辑了我的原始帖子以包含 makeset()。
  • 所有函数原型都需要在 main() 函数之外/之前,因此编译器知道声明和调用这些函数的预期内容。否则,对于 main() 函数中的原型,这些原型“超出范围”,因此不会超出 main() 函数的限制。
  • @user3629249 在main 之外没有调用这些函数。将声明放在函数中是完全可以的,尽管不寻常。
  • @user3629249 关于函数原型:老派(ANSI 前)C 风格建议在方法内部使用函数声明,以避免使用全局函数声明。这与反对使用全局变量的思想流派相同。

标签: c graph-algorithm kruskals-algorithm


【解决方案1】:

一个明显的错误是访问从索引 1 而不是 0 开始的节点数组,这会在您访问最后一个元素时导致缓冲区溢出

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

【讨论】:

  • 没错。并且超限或欠运行可能会影响堆栈上存储在它旁边的变量
  • 检查并扫描了一个错误,这些是我所有问题的根源。谢谢,雷达!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-04-28
  • 2021-05-11
  • 1970-01-01
  • 1970-01-01
  • 2020-07-23
  • 2020-05-14
  • 2020-02-18
相关资源
最近更新 更多