我正在编写一个程序,该程序生成一个无向图并对该图执行BFS。这个图使用了一个邻接列表表示,它建立在我之前构建的list结构的顶部。无论如何,我试图从一个文件加载到图中,然后对它执行BFS,但如果我对一个有30多个顶点的图(从文件加载)执行BFS时,我会在malloc调用中得到一个segfault。然而,如果我不从文件中加载图形,而是手工制作(使用循环和手动添加顶点/边),我可以拥有数千个顶点和10k多条边,并且根本不会发生分段故障。这显然让我认为,我在加载图形数据时所做的事情正在破坏堆,但奇怪的是,失败的malloc调用不在从文件中读取的函数中,而且该函数确实将输入文件正确地转换为图形数据结构,所以我迷失了方向。下面是从输入文件中读取的函数。
以下是我在GDB上的输出:
Program received signal SIGSEGV, Segmentation fault.
_int_malloc (av=0x7ffff7dd3760 <main_arena>, bytes=24) at malloc.c:3766
3766 malloc.c: No such file or directory.
我想强调的是,这个函数内部一定有某种东西导致我的堆损坏,即使损坏要过一段时间才会显示出来。
Graph readFile(char * fn) {
FILE * fp = fopen(fn, "r");
char line[80];
if(fp == NULL) {
fprintf(stderr, "Error : Invalid Filename Argument");
exit(1);
}
fgets(line, 80, fp);
int order = 0;
sscanf(line, "%d", &order);
if(order <= 0) {
fprintf(stderr, "Error parsing input file, order < 0");
exit(1);
}
printf("%dn", order);
Graph new_graph = newGraph(order);
while(fgets(line, 80, fp) != NULL)
{
int origin = -1;
int terminus = -1;
sscanf(line, "%d %d", &origin, &terminus);
printf("%d %dn", origin, terminus);
if(origin > 0 && terminus > 0 && origin <= order && terminus <= order) {
addEdge(new_graph, origin , terminus);
}
else {
break;
}
}
fclose(fp);
//printGraph(stdout, new_graph);
return new_graph;
}
如果我调用这个函数来加载一个图,然后执行BFS,那么下面的malloc调用在List类内的函数中失败
void append(List L, int data) {
if(L == NULL) {
fprintf(stderr, "Error : L null in appendn");
exit(1);
}
printf("Beforen");
Node * new_node = malloc(sizeof(Node)); <-- SEGFAULTS
printf("Aftern");
if(new_node == NULL) {
fprintf(stderr, "Error : Malloc Fail in Append");
}
new_node->data = data;
// printf("Midwayn");
if(L->num_nodes == 0) {
L->front_node = new_node;
L->back_node = new_node;
L->num_nodes++;
return;
}
new_node->prev = L->back_node;
L->back_node->next = new_node;
L->back_node = new_node;
L->num_nodes++;
}
所以我以某种方式修复了它。。事实证明,这与我的readFile函数无关,出于某种原因,这只是导致了错误,尽管与之前测试的数千个顶点相比,我只读取了几个顶点。为了解决这个问题,我简单地改变了每一个
Node * new_node = malloc(sizeof(Node))
呼叫以下
Node * new_node = newNode();
并制作了以下功能
Node * newNode(void) {
Node * new_node = malloc(sizeof(struct NodeObj));
if(new_node == NULL) {
fprintf(stderr, "Error : Malloc returned null node");
exit(1);
}
new_node->prev = NULL;
new_node->next = NULL;
new_node->data = -1;
return new_node;
}
希望这能在未来帮助到别人,我仍然不知道为什么我的堆被破坏了,但现在它似乎工作得更好了。