david12345
david12345

Reputation: 32

array not storing the address of structure

I am trying to implement graph using adjacency list ,according to my knowledge that i have learnt so far if i created variable array pointer to struct adjlistnode of size v*sizeof(struct adjlistnode) thin i can store the addresses of v struct adjlistnode type node in each index of array

Means that each index of array will point to the node of type struct adjlistnode but when i am assigning G->array[i]=NULL it gives me error

||=== Build: Debug in teeest (compiler: GNU GCC Compiler) ===| C:\Users\Mahi\Desktop\DATA STR\teeest\main.c||In function 'creategraph':| C:\Users\Mahi\Desktop\DATA STR\teeest\main.c|59|error: incompatible types when assigning to type 'struct adjlistnode' from type 'void *'| ||=== Build failed: 1 error(s), 0 warning(s) (0 minute(s), 0 second(s)) ===|

why i am not able to assign NULL to index of array

what should i do if i want to access adjacency list like using G->array[i]=first node address adjacent to ith vertex of graph and later i will add another node if needed

struct adjlistnode{
    int dest;
    struct adjlistnode* next;
};
struct graph{
   int V;
   struct adjlistnode* array;
};
struct adjlistnode* getnewnode(int dest){
   struct adjlistnode* newnode =(struct adjlistnode*)malloc(sizeof(struct adjlistnode));
   newnode->dest=dest;
   newnode->next=NULL;
   return newnode;
}
struct graph* creategraph(int v){
   struct graph* G=(struct graph*)malloc(sizeof(struct graph));
   G->V=v;
   G->array=(struct adjlistnode*)malloc(v*sizeof(struct adjlistnode));

   for(int i=0;i<v;i++){
      G->array[i] =NULL;
   }
   return G;

}

Upvotes: 0

Views: 590

Answers (3)

IcedLance
IcedLance

Reputation: 426

G->array[i] returns *(array + i * sizeof(struct adjlistnode)) as if array was struct adjlistnode array[].

What you do is store v objects of struct, but you try to initialize them with NULL, like you would a pointer.

What you probably want is

struct graph{
   int V;
   struct adjlistnode** array;
};

[...]

G->array=(struct adjlistnode**)malloc(v*sizeof(struct adjlistnode*));

That would make array a pointer to an array of pointers.

Then G->array[i] would return a struct adjlistnode* pointer to an object of struct, that you can then initialize with your getnewnode().

Upvotes: 1

Alex Lop.
Alex Lop.

Reputation: 6875

G->array is of type struct adjlistnode *

But

G->array[i] is of type struct adjlistnode.

Thus you cannot assign NULL (of type void *) to G->array[i] of type struct adjlistnode

You should probably have to define array in the struct graph as pointer to pointer

struct graph{
   int V;
   struct adjlistnode** array;
};

and then the following should work for you

struct graph* creategraph(int v){
   struct graph* G=malloc(sizeof(struct graph));
   G->V=v;
   G->array=malloc(v*sizeof(struct adjlistnode*));

   for(int i=0;i<v;i++){
      G->array[i] =NULL;
   }
   return G;

}

** Note1 (as also mentioned by @alk in the comments) that in C, at least since C89 standard, malloc returns void *. void * can be assigned to any other pointer type (and visa versa), thus casting the return value of malloc is not required.

** Note2 (also noted by @alk) that malloc signature is defined with the parameter of type size_t and not int so better to modify the code a little and use the proper type ( Read comparing int with size_t and size_t vs int in C++ and/or C for more info)

Upvotes: 2

P.W
P.W

Reputation: 26800

array is a (single) pointer to struct adjlistnode. So it can be set to NULL.

 G->array = NULL; //is okay

But it is not an array of pointers, so you cannot access the elements of the array and they cannot be set to NULL as well.

For dynamic allocation, you should do this:

struct graph{
   int V;
   struct adjlistnode** array;
};
struct graph* creategraph(int v){
   struct graph* G = malloc(sizeof(struct graph));
   G->V = v;   
   G->array = malloc(v * sizeof(struct adjlistnode*)); //allocation for an array of v pointers 

   for(int i = 0; i < v; i++){    
      G->array[i] = NULL;
   }
   return G;
}

As suggested by @alk, it is better if you pass v as size_t instead of int, as malloc takes size_t.

Upvotes: 1

Related Questions