在C语言中测试和学习图的意外错误

时间:2019-04-26 21:06:50

标签: c directed-graph adjacency-list undirected-graph

我最近开始研究这本关于算法和数据结构的特别书籍SkienaTheAlgorithmDesignManual.pdf,不仅在互联网上,而且在我的大学算法设计老师那里,我都听到了很多赞誉,我最终在第153页(本书本身)或165页(pdf格式)中使用了该书中的某些代码而出现了一些错误。

代码如下:

#include<stdio.h>
#include<stdbool.h>
#include<stdlib.h>
#define MAXV 1000
typedef struct  {
    int y;
    int weight;
    struct edgenode *next;
}edgenode;
typedef struct {
    edgenode *edges[MAXV + 1];
    int degree[MAXV + 1];
    int nvertices;
    int nedges;
    bool directed;
}graph;

void initialize_graph(graph *g, bool directed);
void read_graph(graph *g, bool directed);
void insert_edge(graph *g, int x, int y, bool directed);
void print_graph(graph *g);
void initialize_graph(graph *g, bool directed) {
    int i;

    g->nvertices = 0;
    g->nedges = 0;
    g->directed = directed;
    for (i = 1; i <= MAXV; i++) {
        g->degree[i] = 0;
        g->edges[i] = NULL;
    }

}

void read_graph(graph *g, bool directed) {
    int i;
    int m;
    int x, y;
    initialize_graph(g, directed);
    scanf("%d %d", &(g->nvertices), &m);
    for (i = 1; i <= m; i++) {
        scanf("%d %d", &x, &y);
        insert_edge(g, x, y, directed);
    }
}

void insert_edge(graph *g, int x, int y, bool directed) {
    edgenode *p;
    p = malloc(sizeof(edgenode));
    p->weight = NULL;
    p->y = y;
    p->next = g->edges[x];
    g->edges[x] = p;
    g->degree[x]++;
    if (directed == false)
        insert_edge(g, y, x, true);
    else
        g->nedges++;
}

void print_graph(graph *g) {
    int i;
    edgenode *p;
    for (i = 1; i <= g->nvertices; i++) {
        printf("%d ", i);
        p = g->edges[i];
        while (p != NULL) {
            printf(" %d", p->y);
            p = p->next;
        }
        printf("\n");
    }
}
main() {
    bool directed = true;
    graph *g;
    read_graph(g, directed);
    print_graph(g);
    system("pause");
}

以下是错误:

  
    
      

1> c:\ users \ dragos \ source \ repos \ learninggraph \ learninggraph \ main.c(47):警告C4047:'=':'int'在间接级别上与'void *'不同       1> c:\ users \ dragos \ source \ repos \ learninggraph \ learninggraph \ main.c(49):警告C4133:'=':不兼容的类型-从'edgenode *'到'edgenode *'       1> c:\ users \ dragos \ source \ repos \ learninggraph \ learninggraph \ main.c(65):警告C4133:'=':不兼容的类型-从'edgenode *'到'edgenode *'       1> c:\ users \ dragos \ source \ repos \ learninggraph \ learninggraph \ main.c(73):错误C4700:使用未初始化的局部变量'g'       1>完成的建筑项目“ LearningGraph.vcxproj”-失败。       ===========构建:0成功,1失败,0最新,跳过0 ==========

    
  

我认为主要的问题是“不兼容的类型”,但是我很可能是错的。

2 个答案:

答案 0 :(得分:2)

insert_edge

 p->weight = NULL;

无效,因为 weight int NULL 是指针(通常为(void*)0

insert_edge

 p->next = g->edges[x];

无效,因为 next 是未定义的类型struct edgenode *,但是edges[x]edgenode *。为了解决这个问题,您必须更换

typedef struct {
    int y;
    int weight;
    struct edgenode *next;
}edgenode;

作者

typedef struct edgenode {
    int y;
    int weight;
    struct edgenode *next;
}edgenode;

print_graph行中的原因相同

 p = p->next;

main 的返回类型明确设置为 int

main 中,您调用read_graph g 从未设置/初始化,因此在read_graph中取消引用时,行为是不确定的,这print_graph中也是如此。只需替换

 graph *g;
 read_graph(g, directed);
 print_graph(g);

作者

graph g;
read_graph(&g, directed);
print_graph(&g);

完整修改版:

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

#define MAXV 1000

typedef struct edgenode {
    int y;
    int weight;
    struct edgenode *next;
}edgenode;

typedef struct {
    edgenode *edges[MAXV + 1];
    int degree[MAXV + 1];
    int nvertices;
    int nedges;
    bool directed;
}graph;

void initialize_graph(graph *g, bool directed);
void read_graph(graph *g, bool directed);
void insert_edge(graph *g, int x, int y, bool directed);
void print_graph(graph *g);
void initialize_graph(graph *g, bool directed) {
    int i;

    g->nvertices = 0;
    g->nedges = 0;
    g->directed = directed;
    for (i = 1; i <= MAXV; i++) {
        g->degree[i] = 0;
        g->edges[i] = NULL;
    }

}

void read_graph(graph *g, bool directed) {
    int i;
    int m;
    int x, y;
    initialize_graph(g, directed);
    scanf("%d %d", &(g->nvertices), &m);
    for (i = 1; i <= m; i++) {
        scanf("%d %d", &x, &y);
        insert_edge(g, x, y, directed);
    }
}

void insert_edge(graph *g, int x, int y, bool directed) {
    edgenode *p;
    p = malloc(sizeof(edgenode));
    p->weight = 0;
    p->y = y;
    p->next = g->edges[x];
    g->edges[x] = p;
    g->degree[x]++;
    if (directed == false)
        insert_edge(g, y, x, true);
    else
        g->nedges++;
}

void print_graph(graph *g) {
    int i;
    edgenode *p;
    for (i = 1; i <= g->nvertices; i++) {
        printf("%d ", i);
        p = g->edges[i];
        while (p != NULL) {
            printf(" %d", p->y);
            p = p->next;
        }
        printf("\n");
    }
}

int main() {
    bool directed = true;
    graph g;
    read_graph(&g, directed);
    print_graph(&g);
    system("pause");
}

编译:

pi@raspberrypi:/tmp $ gcc -pedantic -Wall -Wextra g.c
pi@raspberrypi:/tmp $ 

答案 1 :(得分:1)

您从未为restrict_vocab分配任何内存。

不需要将其作为指针,使其成为普通变量并将其地址传递给函数。

graph *g