【发布时间】:2014-02-23 14:15:06
【问题描述】:
我编写了以下程序,每次尝试运行它时都会遇到分段错误。我认为问题出在第 149 行的数组子集的 malloc 上。我尝试使用 gdb 对其进行调试,但它说函数 find 存在问题,这根本没有任何意义。如果有人遇到过类似的问题,请帮忙。非常感谢。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <inttypes.h>
long int N;
// a structure to represent a weighted edge in graph
struct Edge
{
long int src, dest ;
long int weight;
};
// a structure to represent a connected, undirected and weighted graph
struct Graph
{
struct Edge* edge;
};
// A structure to represent a subset for union-find
struct subset
{
long int parent;
long int rank;
long long int vertex;
};
// A utility function to find set of an element i
long int find(struct subset subsets[], long int i)
{
// find the root and make root as parent of i (path compression)
if (subsets[i].parent != i)
subsets[i].parent = find(subsets, subsets[i].parent);
return subsets[i].parent;
}
// Union of two sets of x and y
// (uses union by rank)
void Union(struct subset subsets[],long int x,long int y)
{
long int xroot = find(subsets, x);
long int yroot = find(subsets, y);
// Attach smaller rank tree under root of high rank tree
// (Union by Rank)
if (subsets[xroot].rank < subsets[yroot].rank){
subsets[xroot].parent = yroot;
subsets[yroot].vertex += subsets[xroot].vertex;
}
else if (subsets[xroot].rank > subsets[yroot].rank){
subsets[yroot].parent = xroot;
subsets[xroot].vertex += subsets[yroot].vertex;
}
// If ranks are same, then make one as root and increment
// its rank by one
else
{
subsets[yroot].parent = xroot;
subsets[xroot].rank++;
subsets[xroot].vertex += subsets[yroot].vertex;
}
}
// Compare two edges according to their weights.
// Used in qsort() for sorting an array of edges
int comp(const void* a, const void* b)
{
struct Edge* a1 = (struct Edge*)a;
struct Edge* b1 = (struct Edge*)b;
return (a1->weight - b1->weight);
}
int main(int argc, char *argv[])
{
int j;
long int i;
long int n1, n2, w;
long long int sum=0;
FILE *f = fopen(argv[1], "r");
if (!f) {
exit(EXIT_FAILURE);
}
fscanf(f, "%ld", &N);
struct Graph* graph = (struct Graph*) malloc( sizeof(struct Graph) );
graph->edge = (struct Edge*) malloc( N * sizeof( struct Edge ) );
for (i = 0; i < N-1; i++) {
fscanf(f, "%ld", &n1);
fscanf(f, "%ld", &n2);
fscanf(f, "%ld", &w);
graph->edge[i].src = n1;
graph->edge[i].dest = n2;
graph->edge[i].weight = w;
}
long int x,y;
struct Edge next_edge ;
qsort(graph->edge, N-1, sizeof(graph->edge[0]), comp);
/*
for (i = 0; i < N -1 ; i++)
{
printf("%ld\t %ld\t %ld\n", graph->edge[i].src, graph->edge[i].dest, graph->edge[i].weight);
}
*/
// Allocate memory for creating V subsets
struct subset *subsets = (struct subset*) malloc( N * sizeof(struct subset) );
// Create V subsets with single elements
for (j = 0 ; j < N ; j++)
{
subsets[j].parent = 0;
subsets[j].rank = 0;
subsets[j].vertex = 1 ;
}
i = 0;
while (i < N-1)
{
next_edge = graph->edge[i--];
x = find(subsets, next_edge.src);
y = find(subsets, next_edge.dest);
if (x != y){
sum += graph->edge[i].weight + ( ( graph->edge[i].weight +1 ) * (subsets[x].vertex*subsets[y].vertex-1));
Union(subsets, x, y);
}
}
printf("%lld\n", sum);
return 0 ;
}
附:该程序的目的是,给定一个 MST,以给定的 MST 是它唯一的 MST 的方式计算一棵完整树的权重。
【问题讨论】:
-
你能把代码缩小到麻烦的部分吗?您可以通过在调试器中运行程序来做到这一点,它会在崩溃发生时停止并让您检查调用堆栈(至少请在您的问题中包含它),甚至可以向上走调用堆栈,让您检查值的变量。既然你提到了分段错误,你可能想了解一下the GNU Debugger and read its online manual
标签: c segmentation-fault malloc