Error C2440: 'function' : cannot convert from 'node *' to 'node' - c

I get this error when i try to run the program:
Error C2440: 'function' : cannot convert from 'node *' to 'node'
And i can't figure out what i'm doing wrong when i'm calling the method destroy_node with first_node as argument.
int dequeue(int *data)
{
node *first_node;
int result = 0;
if(queueref.first != NULL){
first_node = queueref.first;
data = (int*) queueref.first->data;
queueref.first = first_node->next;
result = destroy_node(first_node);
}
return result;
}
static int destroy_node(node *node_ref)
{
int data = 0;
free(node_ref);
if(node_ref == NULL){
data = 1;
}
return data;
}
Thanks for the help!
Edit:
The whole class and its this code that givs an error: result = destroy_node(first_node);
#include <stdlib.h>
#include <stdio.h>
typedef struct node {
int data;
struct node *next;
} node;
typedef struct {
struct node *first;
struct node *last;
} queue_c;
static queue_c queueref;
//Funktionsprototyper
#include "queue.h"
static int destroy_node(node node_ref);
static node *create_node(int data);
int enqueue(int data)
{
node *new_node, *last_node;
int result = 0;
new_node = create_node(data);
if(new_node != NULL){
if(queueref.first != NULL){
queueref.first = new_node;
queueref.last = new_node;
}
else{
queueref.last->next = new_node;
queueref.last = new_node;
}
result = 1;
}
return result;
}
static node *create_node(int data)
{
node *noderef;
noderef = (node*) malloc(sizeof(node));
noderef->data = data;
noderef->next = NULL;
return noderef;
}
int dequeue(int *data)
{
node *first_node;
int result = 0;
if(queueref.first != NULL){
first_node = queueref.first;
data = (int*) queueref.first->data;
queueref.first = first_node->next;
result = destroy_node(first_node);
}
return result;
}
static int destroy_node(node *node_ref)
{
free(node_ref);
return node_ref == NULL;
}
void print_queue()
{
node *curr_ptr = queueref.first;
if(curr_ptr != NULL){
while(curr_ptr != NULL){
printf("%d -> ", curr_ptr->data);
curr_ptr = curr_ptr->next;
}
}
else{
printf("Kön är tom!");
}
}
int delete_node(int data)
{
int result = 0;
node *curr_ptr;
node *prev_ptr;
node *temp_ptr;
if(queueref.first == NULL){
printf("Kön är tom!");
}
else if(queueref.first->data == data){
temp_ptr = queueref.first;
queueref.first = queueref.first->next;
result = destroy_node(temp_ptr);
}
else{
prev_ptr = queueref.first;
curr_ptr = queueref.first->next;
while(curr_ptr != NULL){
if(curr_ptr->data == data){
result = 1;
break;
}
prev_ptr = curr_ptr;
curr_ptr = curr_ptr->next;
}
if(result){
temp_ptr = curr_ptr;
prev_ptr->next = temp_ptr->next;
result = destroy_node(temp_ptr);
}
else{
printf("Ingen node innehöll talet: %d", data);
}
}
return result;
}
Edit:
Unwind where right i had forgotten to put a prototype in queue.h and i missed that when i went through the program.

There might be a conflicting prototype; the code as shown shouldn't generate this error. But it also should generate at least a warning since you're calling an unknown function; it would make more sense to put all of destroy_node() before the place where it's called, or add a prototype.
Note that the destroy_node() function is needlessly complex. It could be rewritten as:
static int destroy_node(node *node_ref)
{
free(node_ref);
return node_ref == NULL;
}

Related

How to declare and access a pointer to a member of a member struct in C?

So, I am relatively new to C and trying to implement a Queue using Linked Lists. Here is some code I wrote with help from the internet.
#include <stdio.h>
#include <stdlib.h>
#define pscan(prompt, x) printf(prompt); scanf("%d", &x)
#define nl() printf("\n");
typedef struct Node {
int data;
struct Node* next;
} Node;
typedef struct LinkedList {
Node* head;
Node* tail;
int size;
int (*add) (struct LinkedList*, int, int);
int (*append) (struct LinkedList*, int);
int (*get) (struct LinkedList*, int);
int (*remove) (struct LinkedList*, int);
void (*display_list) (struct LinkedList*);
Node* (*createNode) (int);
} LinkedList;
int add (LinkedList* self, int data, int position);
int append (LinkedList* self, int data);
int get (LinkedList* self, int position);
int rmv (LinkedList* self, int position);
void display_list (LinkedList* self);
LinkedList createLinkedList ();
Node* createNode (int data);
int add(LinkedList* self, int data, int position)
{
if (position > self->size || position < 0)
{
printf("Index out of bounds\n");
return 0;
}
Node* newNode = self->createNode(data);
Node* head = self->head;
Node* tail = self->tail;
if (position == 0)
{
if (head == NULL) self->head = newNode;
else
{
if (tail == NULL) tail = head;
newNode->next = head;
self->head = newNode;
}
self->size++;
}
else if (position == self->size)
{
if (head == NULL) self->head = newNode;
else
{
if (tail == NULL) tail = head;
tail->next = newNode;
self->tail = newNode;
}
self->size++;
}
else
{
Node* prev = head;
for(int i = 0; i < position-1; i++)
{
prev = prev->next;
}
Node* node = prev->next;
prev->next = newNode;
newNode->next = node;
self->size++;
}
return 0;
}
int append(LinkedList* self, int data)
{
return self->add(self, data, self->size);
}
int get(LinkedList* self, int position)
{
if (self->size == 0)
{
printf("The list is empty.");
return 0;
}
else if (position >= self->size || position < 0)
{
printf("Index out of bound.");
return 0;
}
if (position == 0) return self->head->data;
else if (position+1 == self->size) return self->tail->data;
else
{
Node* node = self->head;
for(int i = 0; i < position; i++) node = node->next;
return node->data;
}
}
int rmv (LinkedList* self, int position)
{
int dt;
if (self->size == 0)
{
printf("The list is empty.");
return 0;
}
else if (position >= self->size || position < 0)
{
printf("Index out of bound");
return 0;
}
if (position == 0)
{
Node* head = self->head;
Node* next = head->next;
self->head = next;
dt = head->data;
free(head);
self->size--;
}
else if (position+1 == self->size)
{
Node* node = self->head;
Node* tail = self->tail;
for(int i = 0; i < self->size-2; i++) node = node->next;
node->next = NULL;
self->tail = node;
dt = tail->data;
free(tail);
self->size--;
}
else
{
Node* prev = self->head;
Node* next;
Node* node;
for(int i = 0; i < position-1; i++) prev = prev->next;
node = prev->next;
next = node->next;
prev->next = next;
dt = node->data;
free(node);
self->size--;
}
return dt;
}
void display_list(LinkedList* self)
{
if (self->size == 0) printf("This list is empty.\n\n");
else
{
Node* node = self->head;
printf("[");
for (int i = 0; i < self->size; i++)
{
if (i > 0) printf(", ");
printf("%d", node->data);
node = node->next;
}
printf("]\n\n");
}
}
Node* createNode (int data)
{
Node* node = (Node*) malloc(sizeof(Node));
node->data = data;
node->next = NULL;
return node;
}
LinkedList createLinkedList ()
{
LinkedList l;
l.head = NULL;
l.tail = NULL;
l.add = &add;
l.append = &append;
l.get = &get;
l.remove = &rmv;
l.display_list = &display_list;
l.createNode = &createNode;
l.size = 0;
return l;
}
typedef struct queue
{
LinkedList items;
int *size;
int (*enqueue) (struct queue*, int);
int (*dequeue) (struct queue*);
int (*peek) (struct queue*, int);
void (*display) (struct queue*);
} Queue;
Queue CreateQueue();
int enqueue(Queue* self, int item);
int dequeue(Queue* self);
int peek(Queue* self, int pos);
void display(Queue* self);
Queue CreateQueue()
{
Queue q;
q.items = createLinkedList();
q.size = &(q.items.size);
q.enqueue = &enqueue;
q.dequeue = &dequeue;
q.peek = &peek;
q.display = &display;
return q;
}
int enqueue(Queue* self, int item)
{
self->items.append(&(self->items), item);
return 1;
}
int dequeue(Queue* self)
{
return self->items.remove(&(self->items), 0);
}
int peek(Queue* self, int pos)
{
return self->items.get(&(self->items), pos);
}
void display(Queue* self)
{
printf("%d items in queue.\n", *(self->size));
self->items.display_list(&(self->items));
}
void main()
{
Queue q = CreateQueue();
q.enqueue(&q, 3);
q.enqueue(&q, 7);
q.enqueue(&q, 4);
q.display(&q);
int item = q.dequeue(&q);
printf("Dequeued: %d\n", item);
q.display(&q);
q.enqueue(&q, 14);
q.display(&q);
}
The part I'm having an issue with is making the Queue's size pointer point to the LinkedList's size integer and then accessing that value.
On compiling and running, I get this:
Output from the above code
Thanks in advance.
The problem is in createQueue:
Queue CreateQueue()
{
Queue q;
q.items = createLinkedList();
q.size = &(q.items.size);
q.enqueue = &enqueue;
q.dequeue = &dequeue;
q.peek = &peek;
q.display = &display;
return q;
}
You set q.size to point to q.items.size. This is a pointer to a local variable. You then return a copy of q, but the size member now points to a local that doesn't exist. Dereferencing a pointer to a variable whose lifetime has ended triggers undefined behavior.
There's no need for the size element in Queue. Just access the size element of the items member directly.

Generalized Linked List: Adding Child Link whenever an opening bracket occurs

Here is my code for generating a GLL for the string input: a,(b,c),d where (b,c) will be linked as a child at the next link of a.
GLL* generateList(char poly[])
{
GLL* newNode = NULL, *first = NULL, *ptr = NULL;
while (poly[i] != '\0')
{
if (poly[i] == ')')
{
return first;
}
else
{
if (poly[i] != ',')
{
if (poly[i] != '(')
{
newNode = createNode(poly[i], 0);
}
else
{
++i;
newNode = createNode('#', 1);
newNode->dlink = generateList(poly);
}
}
}
if (first != NULL)
{
ptr = first;
while (ptr->next != NULL)
{
ptr = ptr->next;
}
ptr->next = newNode;
}
else
{
first = newNode;
}
i++;
}
return first;
}
And here is the structure I used for each node.
typedef struct gll
{
int tag;
struct gll* next;
char data;
struct gll* dlink;
} GLL;
I am not finding a way to add that child link to the parent link whenever the bracket opens. The programs runs in a loop.
Note: I have declared i=0 as a global variable to hold the position of character.
Edit: Here is the createNode function
GLL* createNode(char value, int flag)
{
GLL* newNode;
newNode = (GLL *) malloc(sizeof(GLL)*1);
newNode->data = value;
newNode->dlink = NULL;
newNode->tag = flag;
newNode->next = NULL;
return newNode;
}
How do I do it then?
You could do something like that:
#include <stdbool.h>
#include <ctype.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
typedef struct gll
{
int tag;
struct gll* next;
char data;
struct gll* dlink;
} GLL;
GLL* createNode(char value, int flag)
{
GLL* newNode = calloc(1, sizeof(*newNode));
if (!newNode)
return NULL;
newNode->tag = flag;
newNode->data = value;
return newNode;
}
void freeList(GLL *list)
{
for (GLL *current_node = list, *temp; current_node; current_node = temp) {
temp = current_node->next;
freeList(current_node->dlink);
free(current_node);
}
}
GLL* generateList(char *poly, size_t *pos)
{
size_t const length = strlen(poly);
GLL *head = NULL;
GLL *tail = NULL;
for (; *pos < length; ++*pos) {
if (poly[*pos] == '(') {
++*pos; // don't have the next called generateList() read '(' again
tail->dlink = generateList(poly, pos);
if (!tail->dlink) {
freeList(head);
return NULL;
}
continue;
}
else if (poly[*pos] == ')') {
return head;
}
else if (isalpha((char unsigned)poly[*pos])) {
if (!head) {
head = tail = createNode(poly[*pos], 0);
}
else {
tail->next = createNode(poly[*pos], 0);
tail = tail->next;
}
continue;
}
else if (poly[*pos] == ',')
continue;
fputs("Format error :(\n\n", stderr);
freeList(head);
return NULL;
}
return head;
}
void printList(GLL *list)
{
for (GLL *node = list; node; node = node->next) {
printf("%c ", node->data);
if (node->dlink) {
putchar('(');
printList(node->dlink);
printf("\b) ");
}
}
}
int main(void)
{
size_t pos = 0;
GLL *list = generateList("a,(b,(c,d,e(f)),g,h),i,j,k", &pos);
printList(list);
putchar('\n');
freeList(list);
}
Output
a (b (c d e (f)) g h) i j k
Also, if flag is true then it means that the data is not to be considered but there is a child list to be linked.
Sorry, but I don't get how there could be a child list if there is no data for the node.

a singly linked list for all data types, implement insertion, delete and find an element in C language

so i have managed to come up with a syntax for only integers. how do i write the syntax for all data types most preferrably using typedef and void* as well would like to know now to use the void push_back command.?
it creates a linked list, adds nodes, deletes nodes and finds any nodes with in the list.
The first node is always made accessible through a global ‘head’ pointer. This pointer is adjusted when first node is deleted.
Similarly there is a ‘curr’ pointer that contains the last node in the list. This is also adjusted when last node is deleted.
Whenever a node is added to linked list, it is always checked if the linked list is empty then add it as the first node.
Is there anyother way to add,delete and find nodes in a linked list without using #include<stdbool.h> ?
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
struct test_struct
{
int val;
struct test_struct *next;
};
struct test_struct *head = NULL;
struct test_struct *curr = NULL;
struct test_struct* create_list(int val)
{
printf("\n creating list with headnode as [%d]\n",val);
struct test_struct *ptr = (struct test_struct*)malloc(sizeof(struct test_struct));
if(NULL == ptr)
{
printf("\n Node creation failed \n");
return NULL;
}
ptr->val = val;
ptr->next = NULL;
head = curr = ptr;
return ptr;
}
struct test_struct* add_to_list(int val, bool add_to_end)
{
if(NULL == head)
{
return (create_list(val));
}
if(add_to_end)
printf("\n Adding node to end of list with value [%d]\n",val);
else
printf("\n Adding node to beginning of list with value [%d]\n",val);
struct test_struct *ptr = (struct test_struct*)malloc(sizeof(struct test_struct));
if(NULL == ptr)
{
printf("\n Node creation failed \n");
return NULL;
}
ptr->val = val;
ptr->next = NULL;
if(add_to_end)
{
curr->next = ptr;
curr = ptr;
}
else
{
ptr->next = head;
head = ptr;
}
return ptr;
}
struct test_struct* search_in_list(int val, struct test_struct **prev)
{
struct test_struct *ptr = head;
struct test_struct *tmp = NULL;
bool found = false;
printf("\n Searching the list for value [%d] \n",val);
while(ptr != NULL)
{
if(ptr->val == val)
{
found = true;
break;
}
else
{
tmp = ptr;
ptr = ptr->next;
}
}
if(true == found)
{
if(prev)
*prev = tmp;
return ptr;
}
else
{
return NULL;
}
}
int delete_from_list(int val)
{
struct test_struct *prev = NULL;
struct test_struct *del = NULL;
printf("\n Deleting value [%d] from list\n",val);
del = search_in_list(val,&prev);
if(del == NULL)
{
return -1;
}
else
{
if(prev != NULL)
prev->next = del->next;
if(del == curr)
{
curr = prev;
}
else if(del == head)
{
head = del->next;
}
}
free(del);
del = NULL;
return 0;
}
void print_list(void)
{
struct test_struct *ptr = head;
printf("\n -------Printing list Start------- \n");
while(ptr != NULL)
{
printf("\n [%d] \n",ptr->val);
ptr = ptr->next;
}
printf("\n -------Printing list End------- \n");
return;
}
int main(void)
{
int i = 0, ret = 0;
struct test_struct *ptr = NULL;
print_list();
for(i = 5; i<10; i++)
add_to_list(i,true);
print_list();
for(i = 4; i>0; i--)
add_to_list(i,false);
print_list();
for(i = 1; i<10; i += 4)
{
ptr = search_in_list(i, NULL);
if(NULL == ptr)
{
printf("\n Search [val = %d] failed, no such element found\n",i);
}
else
{
printf("\n Search passed [val = %d]\n",ptr->val);
}
print_list();
ret = delete_from_list(i);
if(ret != 0)
{
printf("\n delete [val = %d] failed, no such element found\n",i);
}
else
{
printf("\n delete [val = %d] passed \n",i);
}
print_list();
}
return 0;
}
Is there anyother way to add,delete and find nodes in a linked list without using #include<stdbool.h> ?
Yes, don't use any bool types in your code.

Pointer in function to linked list not updating element in 1 case

I am using a struct like this
struct infoM {
char* direction;
int key;
};
typedef struct nodeM{
struct infoM nodeInfo;
struct nodeM *next;
struct nodeM *prev;
} node;
typedef node list;
I have one function that returns the wanted node by a specific field
node * search(list *l, char* direction) {}
And this is my function to remove elements from the list
int delete(list *l, char* direction) {
node *tmp = search(l, direction);
if (tmp != NULL) {
node *ant = tmp->prev;
node *seg = tmp->next;
if (seg != NULL) {
if (ant != NULL) {
ant->next = seg;
seg->prev = ant;
free(tmp);
return 1;
} else { //prev null
seg->prev = NULL;
*l = *seg;
tmp = NULL;
free(tmp);
return 1;
}
} else { //next null
if (ant == NULL) {
l->nodeInfo.key = somevalue;
l->next = NULL;
l->prev = NULL;
return 1;
} else {
printf("Here is the problem\n");
ant->next = NULL;
free(tmp);
return 1;
}
}
} else { //tmp nulo
perror("Error delete : node null\n");
return 0;
}
}
If I have 4 elements in the list, 1234 and I delete first first element everything is okay and returns 234. If I delete the last element it returns 23 seems to work great. But if I try to delete the last element now the function does nothing despite being the same case that when it is 234 and I don't understand why. The list is not being updated.
In the main I am using the list like this :
list a;
delete(&a, "whatever");
What am I doing wrong ?
This is the code for search
node * createnode(){
node *tmp = (node *) malloc (sizeof(node));
return tmp;
}
node * search(list *l, char* direction) {
node *tmp = createnode();
if (l->nodeInfo.key == 777) {
perror("Error search: empty list\n");
return NULL;
}
tmp=l;
while((strcmp(direction, tmp->nodeInfo.direction) !=0) && (tmp->next != NULL)) {
tmp = tmp->next;
}
if (strcmp(direction, tmp->nodeInfo.direction) == 0) {
return tmp;
} else {
perror("Error search: element not found\n");
return NULL;
}
}

Linked list add() method in C

Where is error the following code?
addNode() function is not run, neither is the traverse() function.
Last data is not shown.
#include <stdio.h>
#include <stdlib.h>
struct isimler{
char isim[10];
struct isimler *next;
};
typedef struct isimler node;
node *head;
void createList(){
int k, n;
node *po;
printf("Eleman Sayisi: "); scanf("%d", &n);
for(k = 0; k<n; k++){
if(k == 0){
head = (node *) malloc(sizeof(node));
po = head;
}else{
po->next = (node *) malloc(sizeof(node));
po = po->next;
}
printf("Isim Girin: "); scanf("%s",po->isim);
}
po->next = NULL;
}
void addNode(){
node *po, *newNode;
po = head;
while(po != NULL){
po = po->next;
}
po = (node *) malloc(sizeof(node));
printf("Isim Girin: "); scanf("%s", po->isim);
po->next = NULL;
}
void traverseList(){
node *po;
int i=0;
po = head;
while(po != NULL){
printf("%d.\t%s\n",i,po->isim);
po = po->next;
i++;
}
}
int main(){
createList();
traverseList();
addNode();
traverseList();
return 1903;
}
Your current addNode() method creates a new node but it doesn't add it to your linked list.
You need to modify your addNode() method like so:
void addNode(){
node *po, *newNode;
po = head;
while(po->next != NULL) { // change this so you don't lose the end of the list
po = po->next; // po is now pointing to the last node in the list
}
newNode = (node *) malloc(sizeof(node)); // change this to newNode
printf("Isim Girin: "); scanf("%s", newNode->isim);
po->next = newNode; // add the new node here, don't set it to NULL
newNode->next = NULL;
}
You can have look this code and get to know where exactly you are having problem
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
struct test_struct
{
int val;
struct test_struct *next;
};
struct test_struct *head = NULL;
struct test_struct *curr = NULL;
struct test_struct* create_list(int val)
{
printf("\n creating list with headnode as [%d]\n",val);
struct test_struct *ptr = (struct test_struct*)malloc(sizeof(struct test_struct));
if(NULL == ptr)
{
printf("\n Node creation failed \n");
return NULL;
}
ptr->val = val;
ptr->next = NULL;
head = curr = ptr;
return ptr;
}
struct test_struct* add_to_list(int val, bool add_to_end)
{
if(NULL == head)
{
return (create_list(val));
}
if(add_to_end)
printf("\n Adding node to end of list with value [%d]\n",val);
else
printf("\n Adding node to beginning of list with value [%d]\n",val);
struct test_struct *ptr = (struct test_struct*)malloc(sizeof(struct test_struct));
if(NULL == ptr)
{
printf("\n Node creation failed \n");
return NULL;
}
ptr->val = val;
ptr->next = NULL;
if(add_to_end)
{
curr->next = ptr;
curr = ptr;
}
else
{
ptr->next = head;
head = ptr;
}
return ptr;
}
struct test_struct* search_in_list(int val, struct test_struct **prev)
{
struct test_struct *ptr = head;
struct test_struct *tmp = NULL;
bool found = false;
printf("\n Searching the list for value [%d] \n",val);
while(ptr != NULL)
{
if(ptr->val == val)
{
found = true;
break;
}
else
{
tmp = ptr;
ptr = ptr->next;
}
}
if(true == found)
{
if(prev)
*prev = tmp;
return ptr;
}
else
{
return NULL;
}
}
int delete_from_list(int val)
{
struct test_struct *prev = NULL;
struct test_struct *del = NULL;
printf("\n Deleting value [%d] from list\n",val);
del = search_in_list(val,&prev);
if(del == NULL)
{
return -1;
}
else
{
if(prev != NULL)
prev->next = del->next;
if(del == curr)
{
curr = prev;
}
else if(del == head)
{
head = del->next;
}
}
free(del);
del = NULL;
return 0;
}
void print_list(void)
{
struct test_struct *ptr = head;
printf("\n -------Printing list Start------- \n");
while(ptr != NULL)
{
printf("\n [%d] \n",ptr->val);
ptr = ptr->next;
}
printf("\n -------Printing list End------- \n");
return;
}
int main(void)
{
int i = 0, ret = 0;
struct test_struct *ptr = NULL;
print_list();
for(i = 5; i<10; i++)
add_to_list(i,true);
print_list();
for(i = 4; i>0; i--)
add_to_list(i,false);
print_list();
for(i = 1; i<10; i += 4)
{
ptr = search_in_list(i, NULL);
if(NULL == ptr)
{
printf("\n Search [val = %d] failed, no such element found\n",i);
}
else
{
printf("\n Search passed [val = %d]\n",ptr->val);
}
print_list();
ret = delete_from_list(i);
if(ret != 0)
{
printf("\n delete [val = %d] failed, no such element found\n",i);
}
else
{
printf("\n delete [val = %d] passed \n",i);
}
print_list();
}
return 0;
}

Resources