Store address dynamic array in c - c

I'm trying to save the address of a dynamic array index. The last line of this function is what gives the pointer error.
static struct sstor *dlist
struct node *ins_llist(char *data, struct llist *l) {
struct node *p, *q;
q = malloc((size_t)sizeof(struct node));
if(q == NULL)
return(NULL);
if(ins_list(data, &dlist))
return NULL;
q->item = &(dlist->item[(dlist->sz)-1]); // Problem?
...}
Allocation of dlist
struct llist *init_llist(void) {
struct llist *l;
dlist = init_list(INITSZ);
if(dlist == NULL)
return(NULL);
This is my node
struct node {
char **item;
struct node *next;
struct node *prev;
};
This is my array
struct sstor {
int sz;
int maxsz;
char item[][1024];
};
I'm still new to pointers. The line below gives the error: assignment from incompatible pointer type
q->item = &(dlist->item[(dlist->sz)-1]);

Presuming that you allocate an actual struct node for q to point to...
The "incompatible pointer types" error arises because q->item has type char ** (a pointer to a pointer to char), and &(dlist->item[...]) has type char (*)[1024] (a pointer to an array of 1024 char). These types simply aren't compatible (there is no actual "pointer to char" object for q->item to point to).
You can fix the problem in two ways. The first is by changing the declaration of struct node to this:
struct node {
char (*item)[1024];
struct node *next;
struct node *prev;
};
The second is by changing both the declaration of struct node to this:
struct node {
char *item;
struct node *next;
struct node *prev;
};
..and changing the assignment statement to this:
q->item = dlist->item[(dlist->sz)-1]; // No Problem!
(The first alternative makes q->item point to the entire array, and the second makes it point to the first char in the array. The perspecacious will note that these are pointers to the same location, but with different types. Usually, the second form is what you want).

char** is not the same as char[][1024]
Try to fix the sstor structure like this:
struct sstor {
int sz;
int maxsz;
char *item[1024];
};

Related

Pass an array of pointers to function argument

I am trying to construct a bus network using adjacent linked list graph data structure.
A simplified code is shown below:
typedef struct BusNetwork
{
struct AdjStopList *stopsArray; //defing the array of pointers
} BusNetwork;
typedef struct Node
{
int stopID;
struct Node *next;
} Node;
typedef struct AdjStopList
{
char stopName[20];
int numOfAdjStp;
struct Node *first;
} AdjStopList;
void insertStopAtLast(AdjStopList *L, int stopID)
{
//add stopID to the last node of the list
return;
}
void addBusRoute(AdjStopList *L[], int from, int to)
{
if (from == to)
return;
insertStopAtLast(L[from], to);
return;
}
void main(BusNetwork *BN, int from, int to)
{
addBusRoute(BN->stopsArray, from, to);
}
The problem is with addBusRoute(BN->stopsArray, from, to); It seems I didn't pass the same type of value as function argument. But my understanding of BN->stopsArray is an array of pointers, which should be the same as AdjStopList L[]. What went wrong?
The argument AdjStopList *L[] has the same meaning as AdjStopList **L.
On the other hand, what is passed BN->stopsArray is struct AdjStopList *.
The argument is a pointer to a pointer to AdjStopList, but what is passed is a pointer to AdjStopList.
Therefore, the type differs.

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;
}
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)
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.
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().

Sorted Insertion in linked list

I'm trying to create a function that does sorted insertion based on two variables, level and name. Apparently I'm having some logic and syntax errors.
My linked list structure:
struct node {
struct node *next;
int level;
char name;
};
My string compare function:
int compare(struct node *one, struct node *two)
{
return strcmp(one->name, two->name);
}
My insertion function:
void insert(struct node **head, const int level, const char name, int(*cmp)(struct node *l, struct node *r))
{
struct node *new =NULL;
/* Find the insertion point */
for (; *head; head = &(*head)->next)
{
if ((*head)->level > level) { // I think this is what is causing the issue
if (compare(*head, new) > 0)
break;
}
}
new = malloc(sizeof *new);
new->level = level;
new->name = name;
new->next = *head;
*head = new;
}
and this is the call stack:
insert(node **head, const int level, const char name, int(*)(node *, node *))
Your syntax error is this line:
return strcmp(one->name, two->name);
The function strcmp expect two char* (aka char pointers) but you give it two char.
The problem is... Do you want
char name;
or
char* name;
That is important in order to get compare right.
Further you need to rearrange your insert function so that you create the new node before using it. Something like:
void insert(struct node **head, const int level, const char name, int(*cmp)(struct node *l, struct node *r))
{
struct node *new =NULL;
// Create and initialize new....
new = malloc(sizeof *new);
new->level = level;
new->name = name;
/* Find the insertion point */
for (; *head; head = &(*head)->next)
{
if ((*head)->level > level) { // I think this is what is causing the issue
if (cmp(*head, new) > 0)
// ^^^ So that you can use it here
break;
}
}
new->next = *head;
*head = new;
}
You are passing a NULL value to the cmp function (?!? probably the correct function is int compare(...). Try to initialize the value of the new variable before to pass it to the function.
You declare node.name to be of type char, but your comparison function is written as if they were null-terminated arrays of char or pointers into such arrays (i.e. C strings). You appear to want this:
struct node {
struct node *next;
int level;
char *name;
};
or maybe this:
struct node {
struct node *next;
int level;
char name[MY_MAXIMUM_NAME_LENGTH_PLUS_ONE];
};
Furthermore, your insert() function passes a NULL pointer to the comparison function as its second argument, because you never allocate any memory for pointer new, and, of course, never assign values to the non-existent members. That doesn't even make sense. What do you think you're comparing to? You seem to want something like this:
struct node *new = malloc(sizeof *new);
if (!new) {
// allocation failure -- abort ...
}
new->level = level;
new->name = /* hmmmm ... */;
Of course, the problem with the type of your names crops up here, too.

Access the content of a pointer declared in a structure

i have the following structure
typedef struct
{
char *head;
char *tail;
int Size_Of_Element;
int Capacity;
}queueHandle;
queueHandle *queue;
and i want to change the value of the memory location that *head points. if it was a simple pointer it would be *head = *content (content is a pointer to an array). I suppose i cannot use the queue -> head = *content, because this is how i change the value of head and not the value that head points to.
You can do that like this:
*(queue->head) = *content

Dereferencing pointer to incomplete type(with well defined structs) in C

I know there are at least 10 questions already about this, but they all point to something I am not doing.
In a header file I have...
typedef struct Node {
struct Node *next;
struct pgmap page;
} Node;
typedef struct linkedlist {
struct Node *head_ptr;
struct Node *tail_ptr;
} LList;
In my c file I have
struct LList mainList;
int main()
{
struct LList *root;
root = &mainList;
root->head_ptr = NULL;
root->tail_ptr = NULL;
...
}
On the root-> lines I get the dereferencing ptr... error. All the threads already on here point to a problem where people accidentally create anonymous structs, such as
typedef struct{
int a;
}; monkey
instead of
typedef struct monkey{
int a;
}; monkey
So what am I missing????
There is no type called "struct LList". The code "typedef struct linkedlist { ... } LList;" creates two type names: one is struct linkedlist, and the other is just LList (without "struct"). You thus need to change "struct LList" to "LList."

Resources