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

时间:2015-02-26 07:40:42

标签: c graph io malloc stdio

我正在编写一个程序,该程序生成无向图并在该图上执行BFS。此图使用邻接列表表示,构建在我之前构建的List结构的顶部。无论如何,我正在尝试从文件中加载图形然后对其执行BFS,但是如果我在具有超过30个顶点的图形(从文件加载)上执行BFS,我在malloc调用期间得到段错误。但是,如果我不从文件中加载图形而是手工制作(使用循环并手动添加顶点/边),我可以拥有数千个顶点和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("%d\n", 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 %d\n", 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,则List类中的函数中的以下malloc调用失败

void append(List L, int data) {
    if(L == NULL) {
        fprintf(stderr, "Error : L null in append\n");
        exit(1);
    }

    printf("Before\n");
    Node * new_node = malloc(sizeof(Node)); <-- SEGFAULTS
    printf("After\n");
    if(new_node == NULL) {
      fprintf(stderr, "Error : Malloc Fail in Append");
    }
    new_node->data = data;

    // printf("Midway\n");
    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++;
}

1 个答案:

答案 0 :(得分:1)

所以我以某种方式解决了它...事实证明不需要处理我的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;
}

希望将来帮助某人,我仍然不知道为什么我的堆已损坏但现在看起来效果更好。