Search code examples
cgraphsegmentation-faultgraph-theoryadjacency-matrix

Segmentation fault when adding edge to graph


I have to use an undirected weighted graph (adjacency matrix) for this program.

typedef struct graph {
  int n;      /* Number of vertices */
  Boolean *visited; /* Will be later used */
  double **mat;  /* It has to be a double */
} Graph;

Function used to initialize the graph:

void InitializeGraph(Graph* g, int max)  {
    int i;

    g->visited = malloc(max * sizeof(Boolean));

    g->mat = calloc(max, sizeof(double*));
    for (i = 0; i < max; i++)
        g->mat = calloc(max, sizeof(double));
    g->n = max;
}

Right now I'm just trying to add an edge to my graph, but for some odd reason it is not working and I don't know why. Here is the function I am trying to use for that:

void Add(Graph *g, int v1, int v2, double weight){
    g->mat[v1][v2] = weight;
    g->mat[v2][v1] = weight;
}

And here is how my program reads the input and how it calls the function Add(). The reading seems to be working fine from what I've tested.

Graph g;
int i, j, aux;
double daux;

scanf("%d%*c", &aux); /* This is the number of vertices */
InitializeGraph(&g, aux);

for(i = 0; i < g.n; i++){
    for(j = 0; j < g.n; j++){
        scanf("%lf%*c", &daux);
        Add(&g, i, j, daux);
    }
}

Running the program on gdb, here is what shows up:

(gdb) run

Starting program: /home/mintroot/Desktop/media

5

0 5 3 2 2

Program received signal SIGSEGV, Segmentation fault.

0x00000000004007a4 in Add ()

Using this command line to compile the program:

gcc -std=c99 -Wall -pedantic -Werror -o media program.c -lm

What am I doing wrong and how can I fix this?


Solution

  • Your initialization function is initializing the matrix incorrectly:

    g->mat = calloc(max, sizeof(double*));
    for (i = 0; i < max; i++)
        g->mat = calloc(max, sizeof(double));
    

    Note that each iteration of the loop is recording the resulting pointer in the same (wrong) place: g->mat. The quickest way to fix it would be this:

    g->mat = calloc(max, sizeof(double*));
    for (i = 0; i < max; i++)
        g->mat[i] = calloc(max, sizeof(double));
    

    For what it's worth, do be aware that your mat is not a 2D array, but rather an array of pointers to 1D arrays. You can access elements via the same syntax you would use with a bona fide 2D array, though, so it may not actually matter to you.

    Props to @Dave, by the way, who earlier posted and then deleted the same code correction.