1

I am implementing graphs using adjacency matrix, but I am unable to solve the segmentation fault. Can anyone help me in guiding dynamic allocation of two dimensional matrix? I also want to know how is 2-D array stored in memory and how it is accessed.

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

struct Graph{
int V; // To represent number the vertex...
int E; //To represent number the Edge.....
int **Adj; // Two dimensional matrix to form the adjacency matrix... 
};


struct Graph *adjMatrixOfGraph(){

        int i;    //for scanning the edges between them .... 
        int u,v; // for loop while initliasing the  adjacency matrix... 
        struct Graph *G=(struct Graph*) malloc(sizeof(struct Graph)); //

        if(!G){
        printf("Memory Error");
        return;
        }

        printf("Number of Vertices");

        scanf("%d",&G->V);
        printf("%d",G->V);
        printf("Number of Edges");
        scanf("%d",&G->E);
        G->Adj=(int **)malloc(sizeof(G->V * G->V)); //allocating memory for G->Adj);
        /*Dynamic memory allocation for Two Dimensional Arrays */

/*      G->Adj = malloc(G->V * sizeof(int )); 
            if(G->Adj == NULL) {         
                 printf( "out of memory\n");     
                }     

         for(i = 0; i < G->V; i++) {     
                G->Adj[i] = malloc(G->V * sizeof(int ));     
                if(G->Adj[i] == NULL) {         
                printf( "out of memory\n");     


                } 
                }
*/

        if(!G->Adj)
        {
        printf("Memory Error");
        return;
        }


        for(u=0;  u < G->V; u++){
        for(v=0; v < G->V; v++){
         //printf("%d %d",u,v); 
         G->Adj[u][v]=0;  //initalising the complete adjacency matrix to zero.
        }
        }

        //Enter the edges.. and the vertices.
        //We are considering this graph as undirected one ... 
        for(i=0;i< G->E;i++)
        {
        scanf("Reading Edges %d %d ",&u,&v);
        G->Adj[u][v]=1;
        G->Adj[u][v]=1;

        //if this graph was directed then we should have considere only one side... 
        //G->V[u][v]=1;

        }


return G;
}

main()
{
struct Graph *G1=adjMatrixOfGraph();

//struct Graph *adjMatrixOfGraph(){
printf("Successful");
return 0;
}
Ernest Friedman-Hill
  • 80,601
  • 10
  • 150
  • 186
Nilesh Agrawal
  • 3,002
  • 10
  • 26
  • 54

2 Answers2

1

Allocating memory for int **Adj is done in the following way:

First you allocate memory for the number of pointers to integers you will have:

Adj = malloc(sizeof(int*) * number_of_integers); /* notice what I pass to sizeof */

Next you allocate memory for each integer individually:

for (i = 0; i < number_of_integers; i++)
    Adj[i] = malloc(sizeof(int) * G->E);

And of course every malloc call needs to be followed by a free call, in a similar fashion.

Notice I don't cast the result of malloc.

I've made a few other changes to your code:

Update your scanf to ensure you have no problems with newlines remaining in the buffer:

    printf("Number of Vertices: ");
    scanf(" %d", &G->V);
    printf("Number of Edges: ");
    scanf(" %d", &G->E);

Initialise them (alternatively, lookup calloc, as it does zero-initialisation for you):

    for(u=0;  u < G->V; u++) // for each vertice
    {
        for(v=0; v < G->E; v++) // for each edge
        {
            G->Adj[u][v] = 0;
        }
    }

The part below I'm not sure about, you manually set the edges to one, right? Shouldn't you use G->V and not G->E?

    for(i = 0; i < G->V; i++)
    {
        printf("Reading vertice u: ");
        scanf(" %d",&u);
        printf("Reading edge v: ");
        scanf(" %d",&v);

        if (u > G->V || v > G->E) // simple error handling 
        {
            printf("Input bigger than size of vertice/edges\n");
            exit(1);
        }

        G->Adj[u][v] = 1;

        G->Adj[u][v] = 1;
    }

I was able to print Successful after this. If you want to make this a little easier, compile your code with the -g flag and if you're on Linux do ulimit -c unlimited. This will create a coredump file every time you get a segfault.

Then to see where the problem is, run gdb your_app core and inside run backtrace. I cannot stress how important it is to use a debugger in these cases.

Community
  • 1
  • 1
Nobilis
  • 7,310
  • 1
  • 33
  • 67
  • number_of_integers means n * n ?, where n is number of rows or coloumns – Nilesh Agrawal Jul 11 '13 at 02:23
  • The number of integers you're planning on storing in the 2D array, if I understand your code correctly, in your case it would be `G->V`. – Nobilis Jul 11 '13 at 02:26
  • @NileshAgrawal I've made some changes to my post, can you please have a look and let me know if it helps you run your code? I'm a little unclear about how big each integer array should be once you've `malloc`-ed. I reckon `malloc` should actually be `Adj[i] = malloc(sizeof(int) * G->E);`. Is this a correct assumption? – Nobilis Jul 11 '13 at 02:34
  • Adj[i]=malloc(sizeof(int) *G->V) – Nilesh Agrawal Jul 11 '13 at 02:44
  • I think `scanf` is also causing you some problems, let me double check the code again. – Nobilis Jul 11 '13 at 02:52
  • @NileshAgrawal I have added some more comments, this should definitely work, if you are still having problems do let me know **what** doesn't work so I can clarify things. – Nobilis Jul 11 '13 at 03:16
  • @NileshAgrawal I can assure you it is, this call is invalid `scanf("Reading Edges %d %d ",&u,&v);` I can assume you were expecting it to print it for you, it doesn't work like this. – Nobilis Jul 11 '13 at 03:18
  • @NileshAgrawal Whew! Glad to be of help, but do follow my suggestion of learning how to use a debugger such as `gdb`, in addition to that, `valgrind` is very useful at tracking memory leaks. Look it up too. – Nobilis Jul 11 '13 at 03:26
1
int **allocate_2D_array(int rows, int columns)
{
    int k = 0;
    int **array = malloc(rows * sizeof (int *) );

    array[0] = malloc(columns * rows * sizeof (int) );
    for (k=1; k < rows; k++)
    {
        array[k] = array[0] + columns*k;
        bzero(array[k], columns * sizeof (int) );
    }

    bzero(array[0], columns * sizeof (int) );

    return array;
}
sundq
  • 735
  • 2
  • 9
  • 28
  • It's a BSD extension, just use `memset (array[0], 0, columns * sizeof (int))` instead. – randomusername Dec 05 '13 at 02:17
  • And `man bzero` shows that `bzero` writes null bytes to a string any way. The rare OS that uses something other than zero for a null pointer will complain. Zero as a null pointer in C does not mean that the internal representation is all zeroes, though that's the way to bet. – Eric Jablow Dec 05 '13 at 02:20