基于链接列表的动态数组图上的realloc函数问题

时间:2014-05-27 15:47:22

标签: c graph linked-list realloc

目前正在进行一些计算机科学练习,当我遇到一个奇怪的问题。 这个练习的想法是使用第一个动态矩阵(没有问题)创建和处理图形,然后使用一系列链接列表。 该练习要求创建函数和数据结构,特别是以下几个:

  • 图表数据结构和链表结构的动态数组
  • 创建图表
  • 添加新节点
  • 添加新边
  • 删除图表
  • 删除边缘
  • 打印图表

我已经创建了所有以前的功能而没有任何问题,但是当我尝试

  1. 创建图表
  2. 添加一些边
  3. 添加新节点
  4. 打印
  5. 图表似乎丢失了链接列表的内存地址,这很奇怪,因为当我这样做时

    1. 创建图表
    2. 添加新节点
    3. 添加一些边
    4. 添加另一个节点
    5. 打印
    6. 测试完美无缺。

      我是realloc函数的新手(我第一次使用动态数组和矩阵),因此,如果我遗漏了某些内容,我确定错误是我的。这就是说你是我正在使用的功能(我只会发布有意义的功能):

      typedef struct edg
      {
          int key;
          struct edg *next;
      } edge;
      
      typedef struct grap
      {
          int nv;
          edge **adj;
      } graph;
      
      graph *makegraph()
      {
          return (graph*)malloc(sizeof(graph));
      }
      
      edge *makeedge()
      {
          return (edge*)malloc(sizeof(edge));
      }
      
      graph *newgraph(int n)
      {
          graph *g;
          int i;
          g = makegraph();
          if(g == NULL)
              printf("Error: mem allocation failure");
          else
              {
                  g->adj = (edge**)malloc(sizeof(edge*));
                      if(g->adj == NULL)
                          {
                              printf("Error: memory allocation failure");
                              free(g);
                              g = NULL;
                          }
                      else
                          {
                              g->nv = n;
                                  for(i = 0; i < n; i++)
                                      g->adj[i] = NULL;
                          }
              }
          return g;
      }
      
      graph* addnode(graph *g)
      {
          edge **e;
          if(g == NULL)
              return NULL;
          e = (edge **)realloc(g->adj, (g->nv+1)*sizeof(edge*));
          if(e == NULL)
              {
                  printf("Errore: failed to relocate memory");
              }
          else
              {
                  g->adj = e;
                  g->adj[g->nv] = NULL;
                  g->nv++;
              }
          return g;
      }
      
      void printgraph(graph *g)
      {
          if( g == NULL || g->adj == NULL)
              {
                  printf("Error: graph not found or NULL");
                  return;
              }
          edge *scroll;
          int i;
          for(i = 0; i < g->nv; i++)
              { 
                  printf("\nEdges node n %d:   ",i+1);
                  if(g->adj[i] != NULL)
                      {
                          printf(" %d  ",(g->adj[i])->key);
                          scroll = g->adj[i]->next;
                              while(scroll != NULL)
                                  {
                                      printf(" %d  ",scroll->key);
                                      scroll = scroll->next;
                                  }
                      }   
              }
      }
      
      edge *addedge(graph *g,int vert1,int vert2)
      {
          if( g == NULL || g->adj == NULL)
              {
                  printf("Error: graph not found or NULL");
                  return;
              }
          if(vert1 > g->nv || vert2 > g->nv || vert1 <= 0 || vert2 <= 0)
              {
                  printf("Node not found");
                  return;
              }
          vert1--;
          edge *tmp,*search;
          tmp = makeedge();
          tmp->next = NULL;
          tmp->key = vert2;
          if (g->adj[vert1] == NULL)
              g->adj[vert1] = tmp;
          else
              {
                  search = g->adj[vert1];
                  while(search->next != NULL)
                      search = search->next;
                  search->next = tmp;
              }
      }
      

      如果我打电话给

      这样的话,这一切都会结束
        

      newgraph - &gt; addnode - &gt; addegdge(尽可能多) - &gt; addnode - &gt;打印

      但是如果我在添加边缘之前没有添加新节点,则会中断。

      本练习的主要目标是创建可以使用相同main()的库。 到目前为止,它确实设法用基于矩阵的结构和这个结构来实现目标,但是前者似乎没有显示出这个问题,后者确实如此。

      非常感谢任何有助于解释这种不便的帮助!

1 个答案:

答案 0 :(得分:0)

在不知道如何使用客户端代码构建图表的情况下,您的数据结构有点难以理解。一方面,你有一个连续的边缘向量,另一方面你有一些类似于链接列表的东西,其中边缘由next指针连接。

当然,您可以维护一个边向量并指向它,但是使用realloc重新分配此向量可能会更改向量的位置,这将使所有指向旧存储器的指针变为非法。 (您的代码非常小心地重新分配给临时变量,因此原始文件不会被覆盖,因此您似乎意识到了这种行为。)

您允许使用n空边创建图形,但只为边缘分配空间。这样:

g->adj = (edge**)malloc(sizeof(edge*));

应该是:

g->adj = malloc(n * sizeof(edge*));

创建图形时,错误分配错误,与图形中的边数不一致。当您在addnode中重新分配时,这是固定的,因为您现在有nv边的空间。

最后一件事:请考虑重命名变量和符号。根据你的结构,你的图表中只有你的边缘,但是它的数字是nv,这是顶点,我估计。 addnode函数不添加节点,它添加空指针。我还没有费心去查看addedge究竟做了什么,但它可能应该是void的结果。这一切都让人很困惑。