#include<stdio.h>
#include<stdlib.h>
int *id,N;
main()
{
FILE* file=fopen("a.txt","r");
int i,p,q,c;
fscanf(file,"%d",&N);
id=(int *)malloc(N*sizeof(int));
for(i=0;i<N;i++)
*(id+i)=i;
while(!feof(file))
{
fscanf(file,"%d %d",&p,&q);
if(!connected(p,q))
unn(p,q);
}
fclose(file);
c=1;
while(c==1)
{
scanf("%d %d",&p,&q);
printf("%d\nYes(1) or No(0) ",connected(p,q));
scanf("%d",&c);
}
}
connected(int p,int q)
{
return((root(p))==(root(q)));
}
unn(int p,int q)
{
int j=root(q);
int i=root(p);
*(id+j)=i;
}
root(int i)
{
while(i!=(*(id+i)))
i=*(id+i);
return(i);
}
编译时,不会显示任何错误消息。但是,当我尝试执行此程序时,它会显示“Segmentation Fault(core dumped)。为什么会发生这种情况? 可能已经注意到,这是尝试实现快速联盟。
快速查找是在没有任何麻烦的情况下使用相同的文件“a.txt”实现的,只需对此代码进行一些调整。 在运行gdb时,它说:
“程序接收信号SIGSEGV,分段故障
0x98048729在rt(i = 134761)at i.c:47“
每次运行变量“i”的值都是134761,它不应该是,因为文本文件中的值只有1到11之间。
*是或否是用户的查询。
答案 0 :(得分:1)
最后的fscanf失败了,你无法分辨。看看gdb的这个输出
a.txt是
5
(只有那个)
当我们运行gdb时我们得到段错误,我们要求发生了它打印了调用堆栈
(gdb) run
Starting program: /home/guido/a.out
warning: Could not load shared library symbols for linux-vdso.so.1.
Do you need "set solib-search-path" or "set sysroot"?
Program received signal SIGSEGV, Segmentation fault.
0x0000000000400911 in root (i=4195888) at a.c:53
53 while(i!=(*(id+i)))
(gdb) where
#0 0x0000000000400911 in root (i=4195888) at a.c:53
#1 0x0000000000400889 in connected (p=0, q=4195888) at a.c:41
#2 0x00000000004007cd in main () at a.c:23
(gdb)
main.c:23是
22 fscanf(file,"%d %d",&p,&q);
23 if(!connected(p,q))
24 unn(p,q);
之后我们看到fscanf p
为0且q
为4195888
(它与您的运行不同,这会发生未定义的行为;)。这是因为scanf没有数字要读取。你的while (!feof(file))
将无效,因为即使我们还没有到达文件末尾,也没有更多的数字(我想我们可以通过扫描“%d%d \ n”来解决这个问题。循环和“%d \ n”在开始时。)
更正确的方法是
22 if(2 == fscanf(file,"%d %d",&p,&q))
23 if(!connected(p,q))
24 unn(p,q);
2
指的是2格式说明符。 scanf
和朋友返回匹配元素的数量。这样我们确保只处理有效的输入。 (这对我来说不是段落错误,我认为它完全解决了这个问题)
我们应该从中得到的是I / O很棘手,我们应该指定准确读取我们想要读取的内容,并注意形成错误的文件。
编辑:顺便说一下,你应该真正声明函数原型并指定返回类型。这是我对代码的“清理”(http://pastebin.com/r0csiCyj)。全球变量也是邪恶的。
答案 1 :(得分:0)
总是检查fopen();
的结果答案 2 :(得分:0)
在你的根函数中你有:
i=*(id+i);
不会检查id + i增量是否在有效范围内,因为您只是用了一段时间来迭代数据结构。问题是,在某些时候,你已经离开了你分配的内存。
一些意见:
干杯