Generic Linked List in C - c

I have a linked_list struct:
typedef struct linked_list{
void *data;
struct linked_list *next;
struct linked_list *previous;
} linked_list;
And some linked list operations:
linked_list *init_linked_list() {
linked_list *ll;
ll = (linked_list *) malloc(sizeof(linked_list));
ll->next = ll;
ll->previous = ll;
return ll;
}
void add_element( linked_list *list, void *element) {
linked_list *list_element;
list_element = malloc(sizeof(linked_list));
list_element->data = element;
list_element->next = list->next;
list->next->previous = list_element ;
list->next = list_element ;
list_element->previous = list;
}
I have a graph struct:
typedef struct graph {
int number_vertices;
vertex **vertices;
} graph;
I have a vertex struct:
typedef struct vertex {
int time;
char *name;
linked_list *edges;
} vertex;
I have a edge struct:
typedef struct edge{
int weight;
int change;
vertex *to;
} edge;
And an "add-edge" function:
void add_edge_to_vertex(vertex *v, int weight, int change, vertex *to) {
edge *pEdge = malloc(sizeof(edge));
pEdge->weight = weight;
pEdge->change = change;
pEdge->to = to;
// add edge to vertex linked list
add_element(v->edges, pEdge);
}
Now to my problem. I setup my graph:
int aSize = 30;
int bSize = 30;
pGraph = malloc(sizeof(graph));
pGraph->vertices = malloc(sizeof(vertex*) * aSize);
pGraph->vertices[0] = malloc(sizeof(vertex) * bSize);
I setup my a vertex and init the linked_list:
vertex *pVertex ;
pVertex = malloc(sizeof(vertex));
pVertex->edges = init_linked_list();
And I add the vertex to my graph:
pGraph->vertices[a][b] = *pVertex;
Last I add an edge between two vertices:
add_edge_to_vertex(&pGraph->vertices[a][i], 100, 0, &pGraph->vertices[a][i+1]);
When I try to fetch the edge weight, I get an segment fault: 11
vertex *v = &pGraph->vertices[0][0];
linked_list *ll = v->edges;
int s = linked_list_size(ll);
printf("%d\n", s); // outputs 1 - works so far!
edge *e = (edge *) ll->data;
int weight = e->weight; // segment fault: 11 ..
I have also tried to add an int and a char to the linked_list struct, and fetched that value, instead of fetching (and casting) edge from the "void *data". This works.
My problem now is, that I don't know if my fault is when I fetch the data, or when I store the data.

Your linked list has one extra node at the start that does not have its data member initialized (the node created by the init_linked_list() function).
When you do :
edge *e = (edge *) ll->data;
you get that first node's data member, which is uninitialized. That causes the segmentation fault when you try to dereference e.
Try this instead :
edge *e = (edge *) ll->next->data;
which will get the data member for the node that was inserted by the last add_element function call. Obviously, this is only safe if there has been at least one element added into the linked list.

Related

Return user defined structure to dynamic array element

I am trying to create a dynamic array to store a linked list in each element of the array. So I defined the linked list structure as below:
//data type for adjacent bus stop
typedef struct AdjStopNode
{
int distance; //travel distance from the bus original stop to this adjcent stop
int stopID;
struct AdjStopNode *prev; //pointer to previous bus stop
struct AdjStopNode *next; //pointer to next bus stop
} AdjStopNode;
AdjStopNode *newAdjStopNode(int distance, int stopID)
{
AdjStopNode *newNode = (AdjStopNode *)malloc(sizeof(AdjStopNode));
assert(newNode != NULL);
newNode->distance = distance;
newNode->stopID = stopID;
newNode->next = NULL;
return newNode;
}
typedef struct AdjStopList
{
char stopname[20];
int numOfAdjStp;
struct BusAtStopList *buslist;
struct AdjStopNode *first; //pointed at the first AdjBusStop of the linked list
struct AdjStopNode *last; //pointed at the first AdjBusStop of the linked list
} AdjStopList;
AdjStopList *newAdjStopList()
{
AdjStopList *newList = (AdjStopList *)malloc(sizeof(AdjStopList));
newList->buslist = newBusAtStopList();
assert(newList != NULL);
memset(newList, NULL, 20 * sizeof(newList[0]));
newList->first = NULL;
newList->last = NULL;
newList->numOfAdjStp = 0;
return newList;
}
Then I defined a dynamic array to store each AdjStopList as an element of the array is as below:
typedef struct BusNetwork
{
int nBusStop; //number of bus stops in the newwork
struct AdjStopList *array;
} BusNetwork;
My function to assign an empty AdjStopList to every element of the array is as below:
//n is the number of AdjStopList
void listToArray(int n)
{
BusNetwork *newBN;
newBN = malloc(sizeof(BusNetwork));
assert(newBN != NULL);
newBN->nBusStop = n;
newBN->array = malloc(n * sizeof(AdjStopList)); //create an array of n number of dejacency lists
for (int i = 0; i < n; i++)
{
newBN->array[i] = newAdjStopList();
}
}
The above code gives me the error at newBN->array[i] = newAdjStopList() as
a value of type "AdjStopList *" cannot be assigned to an
entity of type "struct AdjStopList" C/C++(513)
using VScode.
Could someone help me to fix this problem and explain to me why? Much appreciated.
The type of newBN->array is struct AdjStopList * so the type of newBN->array[i] is struct AdjStopList but the return type fromnewAdjStopList() is struct AdjStopList*. So that should explain the error that you see where you are assigning a struct AdjStopList* to struct AdjStopList in the line
newBN->array[i] = newAdjStopList();
I believe you should change
typedef struct BusNetwork
{
int nBusStop; //number of bus stops in the newwork
struct AdjStopList *array;
} BusNetwork;
to
typedef struct BusNetwork
{
int nBusStop; //number of bus stops in the newwork
struct AdjStopList **array;
} BusNetwork;
So that array becomes an array of pointers to struct AdjStopList. Then that original assignment should work.

How to implement this create function correctly?

I'm trying to make a function to make a priority queue. My structs are this:
struct node {
char *item;
struct node *next;
};
struct queue {
struct node *start;
struct node *end;
};
struct priority_queue {
struct queue **aoq;
int x;
};
My function that I want to implement is:
struct priority_queue *priority_queue_create(int x);
Here, as seen in the structure priority_queue, struct queue **aoq is essentially an array of queues, which is want I want. int x, as in the function header, is the number of queues in the array.
My take on it is this:
struct priority_queue *priority_queue_create(int x) {
struct priority_queue *pq = malloc(sizeof(struct priority_queue));
pq->x = x;
pq->aoq = malloc(x* sizeof(struct queue));
return pq;
}
Where I put the 3 comment lines in the code above is where I suspect my error to be. I want to be able to do something like: if x = 3, there should be an array with 3 queues in it, and I suppose I'll be able to access it by doing something like
pq->aoq[0] /// to access the first queue in the array, or
pq->aoq[2] /// to access the third queue in the array
Can anyone help my fix my implementation? Thanks in advance.
Edit:
Other implementation I've tried:
struct priority_queue *priority_queue_create(int x) {
struct priority_queue *pq = malloc(sizeof(struct priority_queue *));
pq->x = x;
pq->aoq = malloc(x * sizeof(struct queue *));
for (int i = 0; i < x; ++i) {
pq->aoq[i] = malloc(sizeof(struct queue));
}
return pq;
}
From the code that you posted, I think this is the functionality that you want. You were missing the allocation of memory for the queues inside struct priority_queue, that is:
pq-> aoq = malloc( x * sizeof(struct queue *));
Adding this and keeping what you already had (with a sample main function to test the function priority_queue_create()), we have the following code:
#include <stdio.h>
#include <stdlib.h>
struct node {
char *item;
struct node *next;
};
struct queue {
struct node *start;
struct node *end;
};
struct priority_queue {
struct queue **aoq;
int x;
};
struct priority_queue *priority_queue_create(int x) {
struct priority_queue *pq = malloc(sizeof(struct priority_queue *));
pq->x = x;
pq-> aoq = malloc( x * sizeof(struct queue *));
for (int i = 0; i < x; ++i) {
pq->aoq[i] = malloc(sizeof(struct queue)); ///
}
return pq;
}
int main(){
struct priority_queue * pq = priority_queue_create(3);
char * str1 = "abcd";
char * str2 = "abcde";
pq->aoq[0]->start = malloc(sizeof(struct node));
pq->aoq[2]->start = malloc(sizeof(struct node));
pq->aoq[0]->start->item = str1;
pq->aoq[2]->start->item = str2;
printf("%s - %s\n", pq->aoq[0]->start->item, pq->aoq[2]->start->item);
free(pq->aoq[0]->start);
free(pq->aoq[2]->start);
free(pq->aoq[0]);
free(pq->aoq[1]);
free(pq->aoq[2]);
free(pq->aoq);
free(pq);
}

Accessing a struct within array within a struct

What's the correct way of accessing (with a pointer) a variable within a struct within an array within a struct?
I's like to get to variables x and y within position2D with a pointer from function()? Note that I'm traversing the nodes (and the points) in function(), and was hoping to write something like:
draw_point(p->vertices[i]->x, p->vertices[i]->y);
but that doesn't seem to work.
typedef struct Position2D{
uint8_t x;
uint8_t y;
} position2D;
typedef struct Node{
int num;
position2D vertices[4];
struct Node *next;
} node;
/* initialisation: */
node *next1 = NULL; //should be empty
node node1 = {1, {{0,0}, {5,0}, {5,5}, {0,5}}, &next1};
node *next0 = &node1;
node node0 = {0, {{0,10}, {10,10}, {10,15}, {0,15}}, &next0};
node *start = &node0;
/*traverse all nodes and their inner vertices arrays: */
void function(void){
node *p;
for(p = start; p != NULL; p = p->next){
int i;
for (i=0; i<4; i++){ //traverse their four points
//How to get to the x and y at this line?
}
}
vertices is a normal structure variable, not of struct pointer type. While accessing x and y use dot . operator instead of -> operator
Replace below statement
draw_point(p->vertices[i]->x, p->vertices[i]->y);
with
draw_point(p->vertices[i].x, p->vertices[i].y);
EDIT : Another problem in your code while assigning next field.
node node1 = {1, {{0,0}, {5,0}, {5,5}, {0,5}}, &next1};
should be
node node1 = {1, {{0,0}, {5,0}, {5,5}, {0,5}}, (struct Node*)next1};
Here is the working code
#include<stdio.h>
typedef struct Position2D{
int x;
int y;
} position2D;
typedef struct Node{
int num;
position2D vertices[4];
struct Node *next;
} node;
/*traverse all nodes and their inner vertices arrays: */
void function(void){
/* initialisation: */
node *next1 = NULL;
node node1 = {1, {{0,0}, {5,0}, {5,5}, {0,5}}, (struct Node*)next1};
node *next0 = &node1;
node node0 = {0, {{0,10}, {10,10}, {10,15}, {0,15}}, (struct Node*)next0};
node *start = &node0;
node *p = NULL ;
int i=0;
for(p=start;p!=NULL;p=p->next) {
for (i=0; i<4; i++){ //traverse their four points
printf("%d %d \n",p->vertices[i].x, p->vertices[i].y);
}
}
}
int main() {
function();
return 0;
}

Is it possible to store a struct into a linked list?

I'm writing a program that solves a maze using DFS algorithm and stack. I was thinking of storing the coordinates of the path used to get to the end onto a struct containing integers x,y for coordinates and then pushing that struct onto a stack to perform other instructions on (print, pop, etc.).
I have searched all over and have yet to find anything that helps. So I went ahead and set it up but I'm getting an error about type compatibility since I have my node data as an int but I'm trying to put in a struct. Being new to linked lists I have only seen data as an int or char. Finally, is it even possible to do what I want? If not could you suggest a way of passing both x,y coordinates onto the stack? Thank you in advance.
Here's a sample of my code, where to save space a1 is an instance of COORD, and list is initialized as well as the maze and such.
typedef struct node {
int data; /* Value or data stored in node*/
struct node *pNext; /* Reference to the next node address */
} NODE;
/*Structure declares pointers for front and back of the list*/
typedef struct LIST {
NODE *front;
NODE *back;
} LIST;
/* Structure to pass multiple values onto stack */
typedef struct COORD{
int x;
int y;
}COORD;
/*Example of one of the functions */
void lst_push_front(LIST *l, COORD *a1) {
NODE *p = malloc(sizeof(NODE));
p->data = a1;
p->pNext = l->front;
l->front = p;
if(l->back == NULL) // was empty, now one elem
l->back = p;
}
Check the code below.
Since COORD is a structure you can include it in another structure as shown in the below code.
Also make sure that the ordering of the structures are proper.
p->data.x is the right way to access the members of the structure COORD
#include <stdio.h>
/* Structure to pass multiple values onto stack */
typedef struct COORD{
int x;
int y;
}COORD;
typedef struct node {
COORD data; /* --> Changes done here */
struct node *pNext; /* Reference to the next node address */
} NODE;
/*Structure declares pointers for front and back of the list*/
typedef struct LIST {
NODE *front;
NODE *back;
} LIST;
void func(COORD *q)
{
NODE *p = malloc(sizeof(NODE));
p->data.x = q->x;
p->data.y = q->y;
printf("%d %d",p->data.x,p->data.y);
free(p);
}
int main(void) {
COORD *q = malloc(sizeof(COORD));
q->x = 20;
q->y = 30;
func(q);
free(q);
return 0;
}
As #barak manos mentions you should put COORD struct before NODE and change int data to COORD data and use p->data = *a1

C, Sorting a queue of structures

I could use a little help. I'm trying to sort a queue of structures by year.
This are my structures:
struct element{
int id;
int sign;
int year;
int month;
double amount;
struct element *next;
};
struct queue{
struct element *head;
struct element *tail;
struct element *heads;
struct element *temp;
struct element *temph;
int size;
};
and this is the function i wrote:
void sort(struct queue* queue){
if (queue->size == 0){
printf("Struct is empty\n");}
else {
struct element* head=queue->head;
struct element* heads=queue->heads;
struct element* temp=NULL;
struct element* temph=queue->head;
int i, size=queue->size;
for(i=0;i<size-1;i++){
heads=head->next;
if((head->year)>(heads->year)){
temp=head;
head=heads;
heads=temp;
}
head=head->next;
heads=NULL;
temp=NULL;
}
head=temph;
}
}
It breaks when I copmare: if((head->year)>(heads->year)).
I'm pretty sure that my problem is caused by improper reference to the structure next to head (I named it heads).
I omitted all the non-important stuff, and reduced the linked-list bubbele sort to this skeletton.
void sort(struct queue* queue)
{
struct element **pp, *this;
if (!queue->head ){
fprintf(stderr, "OMG Struct is empty\n");
return;
}
for(pp = &queue->head; this = *pp; pp = &(*pp)->next){
struct element *other = this->next;
if (!this->next) break;
if (this->year < other->year) continue;
/*
** Now, Swap this (b) and other (c)
** old situation: #a -> (b) -> (c) -> (d)
** new situation: #a -> (c) -> (b) -> (d)
*/
*pp = other; /* #a -> (c) */
this->next = other->next; /* (b) -> (d) */
other->next = this; /* (c) -> (b) */
}
/* Note: when we get here, "this" will contain the last non-NULL node in the
** chain, and can be used to reset the tail-pointer
*/
return;
}

Resources