C程序中的Segfault可追溯到malloc调用,无法弄清楚原因



我正在编写一个程序,该程序生成一个无向图并对该图执行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;
}

希望这能在未来帮助到别人,我仍然不知道为什么我的堆被破坏了,但现在它似乎工作得更好了。

相关内容

  • 没有找到相关文章

最新更新