2015-12-26 28 views
0

我试图建立一个程序,可以工作与邻接列表或矩阵图,为了做到这一点,老师教我们宣布毗邻为无效*,以便将其作为列表或矩阵进行投射。奇怪的输出的图形与空指针

用下面的代码我得到这个输出: enter image description here

正如你可以看到有很奇怪的事情B中节点挂出。

如果我尝试用代码块调试调试器会在if (L->target != target) {..

我认为有与initGraphList动态分配的问题appendNodeList一个Segmentation Fault,但我不知道如何解决它。

您认为这里的问题是什么?这是分配吗?如果是,我该如何解决? 在此先感谢您的帮助!

代码:

的main.c

#include <stdio.h> 
#include <stdlib.h> 
#include "Graph.h" 

int main(int argc, const char * argv[]) { 
    Graph G = NULL; 
    G = initGraphList(3); 
    addEdgeList(G, 0, 1, 1); 
    addEdgeList(G, 0, 2, 2); 
    addEdgeList(G, 1, 0, 3); 
    addEdgeList(G, 1, 2, 4); 
    addEdgeList(G, 2, 0, 5); 
    addEdgeList(G, 2, 1, 6); 
    printGraphList(G); 
    return 0; 
} 

Graph.h

#include "List.h" 

struct TGraph { 
    void **adj; 
    int nodes_count; 
}; 

typedef struct TGraph *Graph; 

typedef struct AdjList{ 
    List *nodes; 
}AdjList; 

Graph initGraphList(int); 
void printGraphList(Graph G); 
void addEdgeList(Graph G, int source, int target, float peso); 

Graph.c

#include <stdio.h> 
#include <stdlib.h> 
#include "Graph.h" 

Graph initGraphList(int nodes_count){ 
    Graph G = (Graph)malloc(sizeof(struct TGraph)); 
    G->adj = malloc(sizeof(AdjList)); 
    G->nodes_count = nodes_count; 
    ((AdjList *)(G->adj))->nodes = malloc(nodes_count * sizeof(List)); 
    return G; 
} 

void printGraphList(Graph G) { 
    if (G != NULL) { 
     int i; 
     for(i = 0; i < G->nodes_count; i++) { 
      printf("%c -> ", i + 'A'); //I use this in order to print out the nodes as A,B,C,.. instead of 0,1,2,... 
      printList(((AdjList *)(G->adj))->nodes[i]); 
      puts("\n"); 
     } 
    } 
} 

void addEdgeList(Graph G, int source, int target, float peso){ 
    if(G != NULL){ 
     if(source != target){ 
      if(source < G->nodes_count){ 
       if(target < G->nodes_count) 
        ((AdjList*)(G->adj))->nodes[source]= appendNodeList(((AdjList*)(G->adj))->nodes[source], target, peso); 
       else 
        fprintf(stderr, "Il nodo %d non e' compreso nel grafo\n", target); 
      }else 
       fprintf(stderr, "Il nodo %d non e' compreso nel grafo\n", source); 
     }else 
      fprintf(stderr, "Non e' possibile inserire un arco che punta allo stesso nodo\n"); 
    }else 
     fprintf(stderr, "Grafo invalido\n"); 
} 

List.h

struct TList { 
    char target; 
    float peso; 
    struct TList* next; 
}; 

List initNodeList(int info, float peso); 
List appendNodeList(List L, int target, float peso); 
void printList(List L); 

List.c

#include <stdio.h> 
#include <stdlib.h> 
#include "List.h" 

List initNodeList(int info, float peso) { 
    List L = malloc(sizeof(struct TList)); 
    L->target = info; 
    L->peso = peso; 
    L->next = NULL; 
    return L; 
} 

List appendNodeList(List L, int target, float peso) { 
    if (L != NULL) { 
     if (L->target != target) { 
      L->next = appendNodeList(L->next, target, peso); 
     } 
    } else { 
     L = initNodeList(target, peso); 
    } 
    return L; 
} 

void printList(List L) { 
    if (L != NULL) { 
     printf(" %c(%f), ", L->target + 'A', L->peso); 
     printList(L->next); 
    } 
} 
+2

你的头脑创造一个[___MCVE___](http://stackoverflow.com /帮助/ MCVE)? –

+1

除了:;' –

+0

@SouravGhosh 声明指针型的情况下,如果它的类型名和类型的随后的变量使用样式匈牙利记号来提示关闭读取器,如'typedef结构TGraph * pGraph使代码更易读它现在应该是一个MCVE,我删除了免费函数并添加了头文件来包含并将Graph.h与AdjList.h合并。 @WeatherVane我认为我是用'typedef结构TGraph *图形;'也许我不明白你的意思。 – Aster

回答

0

首先你忘了初始化你用NULL指针数组。这是我在代码中发现的主要错误。

如果你做任何指针的typedef避免出现误导的名称(例如添加后缀 “PTR”到类型名)

typedef struct TList { 
    char target; 
    float peso; 
    struct TList* next; 
} *TListPtr; 

typedef struct TAdjList{ 
    TListPtr *nodes; 
} *TAdjListPtr; 

没有必要的void **adjTAdjListPtr *adj做你想做的事

typedef struct TGraph { 
    TAdjListPtr adj; 
    int nodes_count; 
} *TGraphPtr; 

TListPtr initNodeList(int info, float peso) { 
    TListPtr L = malloc(sizeof(struct TList)); 
    L->target = info; 
    L->peso = peso; 
    L->next = NULL; 
    return L; 
} 

TListPtr appendNodeList(TListPtr L, int target, float peso) { 
    if (L != NULL) { 
     if (L->target != target) { 
      L->next = appendNodeList(L->next, target, peso); 
     } 
    } else { 
     L = initNodeList(target, peso); 
    } 
    return L; 
} 

void printList(TListPtr L) { 
    if (L != NULL) { 
     printf(" %c(%f), ", L->target + 'A', L->peso); 
     printList(L->next); 
    } 
} 

你必须用NULL初始化你的指针数组。为此,请使用memset

TGraphPtr initGraphList(int nodes_count){ 
    TGraphPtr G = malloc(sizeof(struct TGraph)); 
    G->adj = malloc(sizeof(TAdjList)); 
    G->nodes_count = nodes_count; 
    G->adj->nodes = (TListPtr*)malloc(nodes_count * sizeof(TListPtr)); 
    memset(G->adj->nodes, 0, nodes_count * sizeof(TListPtr)); 
    return G; 
} 

void printGraphList(TGraphPtr G) { 
    if (G != NULL) { 
     int i; 
     for(i = 0; i < G->nodes_count; i++) { 
      printf("%c -> ", i + 'A'); //I use this in order to print out the nodes as A,B,C,.. instead of 0,1,2,... 
      printList(G->adj->nodes[i]); 
      puts("\n"); 
     } 
    } 
} 

void addEdgeList(TGraphPtr G, int source, int target, float peso){ 
    if(G != NULL){ 
     if(source != target){ 
      if(source < G->nodes_count){ 
       if(target < G->nodes_count) 
        G->adj->nodes[source] = appendNodeList(G->adj->nodes[source], target, peso); 
       else 
        fprintf(stderr, "Il nodo %d non e' compreso nel grafo\n", target); 
      }else 
       fprintf(stderr, "Il nodo %d non e' compreso nel grafo\n", source); 
     }else 
      fprintf(stderr, "Non e' possibile inserire un arco che punta allo stesso nodo\n"); 
    }else 
     fprintf(stderr, "Grafo invalido\n"); 
} 
+0

谢谢!这个memset确实是我所需要的,为了让它正常工作! 无论如何,我仍然需要使用'void **',因为我必须将对象作为List和Matrix对待。 矩阵结构如下: 'typedef struct AdjMatrix { float ** nodes; } AdjMatrix' 所以我还是需要转换'无效**'作为'AdjMatrix'或作为'AdjList'。 – Aster

0

消除编译errors.and警告

只是不添加错误检查后,这是结果。

注::我没有检查这个代码,任何不确定的行为

#include <stdio.h> 
#include <stdlib.h> 


struct TList 
{ 
    size_t target; 
    float peso; 
    struct TList* next; 
}; 
//typedef struct TList * List; 

struct TList * initNodeList(size_t info, float peso); 
struct TList * appendNodeList(struct TList * L, size_t target, float peso); 
void printList(struct TList * L); 

struct TGraph 
{ 
    struct TList **nodes; 
    size_t nodes_count; 
}; 

//typedef struct TGraph * Graph; 



struct TGraph * initGraphList(size_t); 
void printGraphList(struct TGraph *); 
void addEdgeList(struct TGraph *, size_t, size_t, float); 



int main(void) 
{ 
    struct TGraph * G = NULL; 
    G = initGraphList(3); 
    addEdgeList(G, 0, 1, 1); 
    addEdgeList(G, 0, 2, 2); 
    addEdgeList(G, 1, 0, 3); 
    addEdgeList(G, 1, 2, 4); 
    addEdgeList(G, 2, 0, 5); 
    addEdgeList(G, 2, 1, 6); 
    printGraphList(G); 
    return 0; 
} // end function: main 


struct TList * initNodeList(size_t info, float peso) 
{ 
    struct TList * L = malloc(sizeof(struct TList)); 
    L->target = info; 
    L->peso = peso; 
    L->next = NULL; 
    return L; 
} // end function: initNodeList 


struct TList * appendNodeList(struct TList * L, size_t target, float peso) 
{ 
    if (L != NULL) 
    { 
     if (L->target != target) 
     { 
      L->next = appendNodeList(L->next, target, peso); 
     } 
    } 

    else 
    { 
     L = initNodeList(target, peso); 
    } 
    return L; 
} // end function: appendNodeList 


void printList(struct TList * L) 
{ 
    if (L != NULL) 
    { 
     printf(" %c(%f), ", (char)L->target + 'A', L->peso); 
     printList(L->next); 
    } 
} // end function: printList 


struct TGraph * initGraphList(size_t nodes_count) 
{ 
    struct TGraph * G = malloc(sizeof(struct TGraph)); 
    G->nodes_count = nodes_count; 
    G->nodes = malloc(nodes_count * sizeof(struct TList *)); 
    return G; 
} // end function: initGraphList 


void printGraphList(struct TGraph * G) 
{ 
    if (G != NULL) 
    { 
     for(size_t i = 0; i < G->nodes_count; i++) 
     { 
      printf("%c -> ", (char)i + 'A'); //I use this in order to print out the nodes as A,B,C,.. instead of 0,1,2,... 
      printList(G->nodes[i]); 
      puts("\n"); 
     } 
    } 
} 

void addEdgeList(struct TGraph * G, size_t source, size_t target, float peso) 
{ 
    if(G != NULL) 
    { 
     if(source != target) 
     { 
      if(source < G->nodes_count) 
      { 
       if(target < G->nodes_count) 
        G->nodes[source]= appendNodeList(G->nodes[source], target, peso); 
       else 
        fprintf(stderr, "Il nodo %c non e' compreso nel grafo\n", (char)target); 
      } 

      else 
       fprintf(stderr, "Il nodo %c non e' compreso nel grafo\n", (char)source); 
     } 

     else 
      fprintf(stderr, "Non e' possibile inserire un arco che punta allo stesso nodo\n"); 
    } 

    else 
     fprintf(stderr, "Grafo invalido\n"); 
} 

,输出是:

A -> B(1.000000), C(2.000000), 

B -> A(3.000000), C(4.000000), 

C -> A(5.000000), B(6.000000), 
+0

非常感谢您的帮助,但我需要治疗adiacensies无论是作为一个数组或矩阵,为了做到这一点我必须声明adiacensies作为'无效**'(至少我所知道的和何老师教我)所有我从我的代码中遗失的是一个memset设置NULL列表,它现在工作正常。 我仍然感谢您的时间和精力! – Aster