Neri-kun
Neri-kun

Reputation: 193

Unexpected error in testing and learning about graphs in C

I have recently started to study this particular book for algorithms and data structure SkienaTheAlgorithmDesignManual.pdf, from which I've heard a lot of praise not only on the Internet,but from my Algorithms Design teacher as well at college,and I ended up having some errors with some code used from the book on page 153(on the book itself) or 165(pdf format).

Here's the code:

#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");
}

Here are the errors:

1>c:\users\dragos\source\repos\learninggraph\learninggraph\main.c(47): warning C4047: '=': 'int' differs in levels of indirection from 'void *' 1>c:\users\dragos\source\repos\learninggraph\learninggraph\main.c(49): warning C4133: '=': incompatible types - from 'edgenode *' to 'edgenode *' 1>c:\users\dragos\source\repos\learninggraph\learninggraph\main.c(65): warning C4133: '=': incompatible types - from 'edgenode *' to 'edgenode *' 1>c:\users\dragos\source\repos\learninggraph\learninggraph\main.c(73): error C4700: uninitialized local variable 'g' used 1>Done building project "LearningGraph.vcxproj" -- FAILED. ========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

I think that the main problem is the "incompatible types",but I may be as very well be wrong.

Upvotes: 0

Views: 57

Answers (2)

bruno
bruno

Reputation: 32586

In insert_edge

 p->weight = NULL;

is invalid because weight is an int but NULL a pointer (typically (void*)0)

In insert_edge

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

is invalid because next is the undefined type struct edgenode * but edges[x] is edgenode *. To solve that you have to replace

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

by

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

The reason is the same in print_graph line

 p = p->next;

Explicitly set the return type of main as int

In main you call read_graph with g never set/initialized so when it is dereferenced in read_graph the behavior is undefined, and this is also the case in print_graph. Just replace

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

by

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

Full modified version :

#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");
}

Compilation :

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

Upvotes: 2

Barmar
Barmar

Reputation: 780688

You never allocated any memory for graph *g.

There's no need for this to be a pointer, make it a normal variable and pass its address to the functions.

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

Upvotes: 1

Related Questions