-1
#include<stdio.h>
#include<stdlib.h>
struct Graph{
int V;
int E;
int **Adj;
};
struct Graph* adjMatrix(){
int u,v,i;
struct Graph *G;
G=(struct Graph*)malloc(sizeof(struct Graph));
if(!G){
    printf("Memory Error!\n");
    return;
}
printf("Enter number of nodes and number of edges:\n");
scanf("%d %d",&G->V,&G->E);
G->Adj=malloc((G->V)*(G->V)*sizeof(int));
for(u=0;u<(G->V);u++)
    for(v=0;v<(G->V);v++)
        G->Adj[u][v]=0; //This gives a segmentation fault.


printf("Enter node numbers in pair that connect an edge:\n");
for(i=0;i<(G->E);i++){
    scanf("%d %d",&u,&v);
    G->Adj[u][v]=1;
    G->Adj[v][u]=1;
}
return(G);
}
int main(){
struct Graph *G;
int i,j,count=0;
G=adjMatrix();
for(i=0;i<G->V;i++){
    for(j=0;j<G->V;j++){
        printf("%d ",G->Adj[i][j]);
        count++;
    }
    if(count==G->V)
        printf("\n");
}
return 0;
}

The code shows segmentation fault when I tried to assign a value in 2D array i.e. at G->Adj[u][v]=0; but I don't know what is wrong with that? Because It's simply a assignment to the array.

2 Answers2

0

The segmentation fault is casued due-to error at the 2D array allocation method, as it us done at the following line:

G->Adj=malloc((G->V)*(G->V)*sizeof(int));.

which actually allocated a 1D buffer of (G->V)*(G->V) integers, so it can't enable a later access in syntax of 2D, like you want

In a nutshell: when allocation 2D array like you wish, you should first allocate the 1D array of pointers. At your code, should be:

G->Adj = (int **)malloc(sizeof(int *)*G->V);

And then allocate G->V vectors per pointer:

for(i=0; i < G->V; i++) 
{
    G->Adj[i] = (int *)malloc(sizeof(int)*G->V);
}

furthermore, a good practice is to verify allocation result is not NULL (malloc failure), for each allocation

for general explanation on c vectors allocation you may read more at Method 2: the "can still use [r][c] syntax to access" way

Besides that, memory release is missing at the end of your program, so you should add calls to free() at the opposite order (vectors and then pointers)

GM1
  • 380
  • 3
  • 14
  • [Do I cast the result of malloc?](https://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc) – KamilCuk Jan 22 '19 at 09:53
  • That's not a 2D array. That's an array of pointers to one-dimensional arrays. See https://stackoverflow.com/questions/42094465/correctly-allocating-multi-dimensional-arrays – Andrew Henle Jan 22 '19 at 10:11
  • It's a matter of perspective. For the asked 2D array, continuous memory is irreverent, so the answered method serves as such. like answered at the end of the link you posted, "C don't have multidimensional arrays". But you could have arrays of arrays (or of other aggregates) and arrays of pointers." but anyway the allocation method there is also valid of course. both would not get segmentation fault and serve the same purpose here – GM1 Jan 22 '19 at 10:44
0
#include<stdio.h>
#include<stdlib.h>
struct Graph{
int V;
int E;
int **Adj;
};
struct Graph* adjMatrix(){
int u,v,i;
struct Graph *G;
G=malloc(sizeof(struct Graph));
if(!G){
    printf("Memory Error!\n");
    return 0;
}
printf("Enter number of nodes and number of edges:\n");
scanf("%d %d",&G->V,&G->E);
//First problem was here this is how you allocate a 2D array dynamically 
G->Adj=malloc((G->V)*sizeof(int*));
for(u=0;u<G->V;u++)
    G->Adj[u]=malloc((G->V)*sizeof(int));
for(u=0;u<(G->V);u++)
    for(v=0;v<(G->V);v++)
        G->Adj[u][v]=0; //This gives a segmentation fault.

    // i added some adjustment here to help you 
       printf("Enter node numbers in pair that connect an edge:\n");
    for(i=0;i<(G->E);i++){
    scanf("%d %d",&u,&v);
    if(u>=G->V || v>=G->V){
    printf("Error give the right input\n");
    i--;}
    else{
    G->Adj[u][v]=1;
    G->Adj[v][u]=1;}
}
return(G);
}
int main(){
struct Graph *G;
int i,j,count=0;
G=adjMatrix();
for(i=0;i<G->V;i++){
    for(j=0;j<G->V;j++){
        printf("%d ",G->Adj[i][j]);
        count++;
    }
    if(count==G->V)
        printf("\n");
}
return 0;
}
Spinkoo
  • 2,080
  • 1
  • 7
  • 23
  • `G->Adj=malloc((G->V)*sizeof(int));` is invalid. – KamilCuk Jan 22 '19 at 09:54
  • you mean it should be sizeof(int*)? because they are both of size 4 – Spinkoo Jan 22 '19 at 09:58
  • 1
    `they are both of size 4` - they _could_ be both of size 4. If `CHAR_BIT=8` then `sizeof(int)` must be at least 2, but that's at least, so it could be 2, 3, 4, 8. `sizeof(int*)` is the size of an int pointer, it can be 4 on 32-bit archutecture, but on 64-bit it's 8, on 8-bit processor with 256 bytes of ram it will be 1. It's bad to assume the output of `sizeof(type)` (maybe except `sizeof(char)`.) – KamilCuk Jan 22 '19 at 10:01