Node deletion in linked list from beginning - c

I want to delete the first node and return the value of the deleted node. But I an getting this warning:
warning: assignment from incompatible pointer type [-Wincompatible-pointer-types]
example=(**example).next;
So, my code does not work. Can anyone help me to fix this? Thanks.
struct myStruct {
int data;
struct myStruct next;
}
int deleteNode(struct myStruct **example) {
struct myStruct *temporary;
if (temporary == NULL) {
emptyNode(temporary); // this function only returns NULL
}
temporary = *example;
example = (**example).next;
free(temporary);
return (**example).data;
}

This structure declaration contains at least two typos.
struct myStruct
{
int data;
struct myStruct next;
}
The first one is that there is no semicolon after the closing brace. And the second one is that the data member next must have pointer type.
It seems you mean
struct myStruct
{
int data;
struct myStruct *next;
};
As for the error message then in this assignment
example=(**example).next;
the left side hand operand has the type struct myStruct ** while the right hand side operand has the type struct myStruct * and these pointer types are not compatible. So the compiler issues an error.
Nevertheless the function in any case is invalid because you are using uninitialized variables like
struct myStruct *temporary;
if(temporary==NULL)
//...
The function interface is bad.because it is unclear what the function returns in case when it is called for an empty list.
The function can be declared and defined the following way.
int deleteNode( struct myStruct **example, int *data )
{
int success = *example != NULL;
if ( success )
{
struct myStruct *temporary = *example;
*example = ( *example )->next;
*data = temporary->data;
free( temporary );
}
return success;
}
And it can be called as it is shown below
#include <stdio.h>
#include <stdlib.h>
struct myStruct
{
int data;
struct myStruct *next;
};
int deleteNode( struct myStruct **example, int *data )
{
int success = *example != NULL;
if ( success )
{
struct myStruct *temporary = *example;
*example = ( *example )->next;
*data = temporary->data;
free( temporary );
}
return success;
}
int main(void)
{
struct myStruct *head = 0;
// fill the list
int data;
if ( deleteNode( &head, &data ) )
{
printf( "The deleted value is %d\n", data );
}
else
{
puts( "The list is empty." );
}
return 0;
}

Related

struct that holds struct, how to dereference

i have couple of linked lists in my larger program which i now want to keep in a struct (t_holder).
typedef struct s_list
{
int val;
struct t_list *next;
} t_list;
typedef struct s_holder
{
t_list *a_starts;
// more lists...
} t_holder;
now i try to figure out how i dereference this in my program.
void try_out(t_holder *list_holder, int num)
{
//assigning something to a_starts
list_holder->a_starts->val = num;
}
int main(int argc, char *argv[])
{
t_holder *list_holder;
int num;
num = 42;
list_holder = NULL;
try_out(list_holder, num);
return (0);
}
in the function "try_out" i simlpy try to assign a value to a_starts->val but my debugger shows me ACCESS_ERROR if i declare it like this
list_holder->a_starts->val = num;
For starters this typedef declarations
typedef struct s_list
{
int val;
struct t_list *next; // <===
} t_list;
is incorrect. It seems you mean
typedef struct s_list
{
int val;
struct s_list *next; // <===
} t_list;
As for your other code then you declared a null pointer
t_holder *list_holder;
//...
list_holder = NULL;
So dereferencing the null pointer results in undefined behavior.
You need to write something like the following
t_holder list_holder = { .a_starts = NULL };
//...
try_out( &list_holder, num);
and then within the function something like
void try_out(t_holder *list_holder, int num)
{
t_list *node = malloc( sizeof( *node ) );
node->val = num;
node->next = list_holder->a_starts;
list_holder->a_starts = node;
}

small linked list programme in c, random printf output

Im writing a little school programme, I have to use 'void const *content' as a parameter.
I'm having trouble printing the content of the new node. without 'const' the code works and displays everything correct. could someone point out what I'm doing wrong?
terminal output:
�
6
#include <stdio.h>
#include <stdlib.h>
typedef struct s_list
{
void *content;
size_t content_size;
struct s_list *next;
} t_list;
t_list *lstnew(void const *content, size_t content_size)
{
struct s_list *new = (struct s_list*)malloc(sizeof(struct s_list*));
if(new == NULL){
printf("No allocation!");
exit(1);
}
new->content = &content;
new->content_size = content_size;
new->next = NULL;
return(new);
}
int main(void)
{
printf("%s\n", lstnew("Hello", 6)->content);
printf("%zu\n", lstnew("Hello", 6)->content_size);
return(0);
}
You're taking the address of a local variable here:
new->content = &content;
Instead, just take the value:
new->content = content;
Also, you don't allocate enough memory here; you're only allocating enough for the pointer instead of the size of the structure:
struct s_list *new = (struct s_list*)malloc(sizeof(struct s_list*));
The cast on malloc is also unnecessary. I would write it like this:
struct s_list *new = malloc(sizeof(*new));
Instead of using a typedef and t_list, you should just use struct s_list everywhere, because the structure is not intended to be opaque.
In this declaration
struct s_list *new = (struct s_list*)malloc(sizeof(struct s_list*));
instead of allocation memory for an object of the type struct s_list there is being allocated memory for pointer of the type struct s_list *.
You have to write either
struct s_list *new = malloc( sizeof( struct s_list ) );
or
t_list *new = malloc( sizeof( t_list ) );
In this statement
new->content = &content;
the left-side operand has the type void * while the right-hand operand has the type const void **. Moreover you are using a pointer to the local variable content (function parameters are its local variables) that will not be alive after exiting the function.
What you need is to allocate memory and copy the content of the variable content in the allocated memory.
Here is a demonstrative program that shows how the function can be defined.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct s_list
{
void *content;
size_t content_size;
struct s_list *next;
} t_list;
t_list * lstnew( const void *content, size_t content_size )
{
t_list *new = malloc( sizeof( t_list ) );
if ( new != NULL )
{
new->content = malloc( content_size );
if ( new->content == NULL )
{
free( new );
new = NULL;
}
else
{
memcpy( new->content, content, content_size );
new->content_size = content_size;
new->next = NULL;
}
}
return new;
}
int main(void)
{
t_list *head = lstnew( "Hello", 6 );
head->next = lstnew("World!", 7 );
printf( "%s %s\n", ( char * )head->content, ( char * )head->next->content );
return 0;
}
The program output is
Hello World!

Dereferencing pointer to incomplete type

I am new to C programming and as a mini project I decided to try to implement a stack in C using OOP style structure in a file GenericStack.h as shown below:
void _GENERICSTACK0001(void *,void *);
void *_GENERICSTACK0002(void *);
int _GENERICSTACK0003(void *);
typedef struct
{
struct GenericStackNode *next;
void *data;
int type;
}GenericStackNode;
typedef struct
{
struct GenericStackNode *top;
int count;
void (*add)(void *,void *);
void *(*pop)(void *);
int (*hasNext)(void *);
int (*getCount)(void *);
}GenericStack;
GenericStack newGenericStack()
{
GenericStack *genStack = malloc(sizeof(GenericStack));
genStack->add = _GENERICSTACK0001;
genStack->pop = _GENERICSTACK0002;
genStack->hasNext = _GENERICSTACK0003;
genStack->getCount = _GENERICSTACK0003;
genStack->top=NULL;
genStack->count = 0;
return *genStack;
}
void _GENERICSTACK0001(void *self,void *data)//add
{
GenericStack *genStack = self;
if(genStack->top == NULL)
{
genStack->top = malloc(sizeof(GenericStackNode));
genStack->top->next = NULL;
genStack->top->type = 0;
genStack->top->data = data;
}
else
{
GenericStackNode *temp = malloc(sizeof(GenericStackNode));
temp->next = genStack->top;
temp->type = 0;
temp->data = data;
genStack->top = temp;
genStack->count++;
}
}
void *_GENERICSTACK0002(void *self)//pop
{
GenericStack *genStack = self;
void *data = NULL;
if(genStack->top == NULL)
{
return data;
}
else
{
GenericStackNode *temp = genStack->top;
genStack->top = genStack->top->next;
data = temp->data;
free(temp);
genStack->count--;
return data;
}
}
int _GENERICSTACK0003(void *self)
{
GenericStack *genStack = self;
return genStack->count;
}
All I need to know is why (among many others) I get the specific error:
GenericStack.h:41:16: error: dereferencing pointer to incomplete type
genStack->top->type = 0;
I have checked the other answers on stackoverflow concerning "dereferencing pointer to incomplete type" but I cant seem to understand.
You're getting an error from GenericStack, but you have a problem in both GenericStack and GenericStackNode.
In C, struct X and X are different types. When you write:
struct GenericStackNode *next;
it declares a type called struct GenericStackNode (and a member which is a pointer to that type). This type is incomplete because you have not provided the struct definition.
The type could be completed by providing a struct definition later, but you never do that. Instead, you define an unnamed struct and typedef GenericStackNode to it , but that has no effect on struct GenericStackNode.
Then, struct GenericStackNode *top; still uses this same incomplete type, not the struct you defined above.
Assuming you meant for this pointer to be a pointer to the same type of struct it's contained in, you could use this pattern for both of your structs:
typedef struct X X;
struct X
{
X *ptr;
};
Often people combine the typedef with the struct definition but I find it clearer to have them separate.
You already type-defined GenericStackNode as a type, there is no need for struct GenericStackNode anymore, just GenericStackNode :
typedef struct
{
struct GenericStackNode *top;
...
}
should be only
typedef struct
{
GenericStackNode *top;
...
}
also , you can't use GenericStackNode when you still havn't defined it yet :
typedef struct
{
struct GenericStackNode *next;
void *data;
int type;
} GenericStackNode ;
you can write :
typedef struct GenericStackNode
{
struct GenericStackNode *next;
void *data;
int type;
} GenericStackNode ;

Is this correct implementation of my initialize List function for a Linked list?

Everywhere I look about Linked List implementation, I see that when I initialize a list my code should look something like this:
typedef struct node {
int val;
struct node * next;
} node_t;
But my assignment says this for my initialize function: Write a function initializeList which creates a linked list of employee information where each node contains an employeeData struct and a pointer called next.
What I got from that is to do this, but I dont think its right:
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
FILE * data;
typedef struct{ // Main struct containing needed data types
int EMP_ID;
int dep;
int rank;
double salary;
char name[20];
} node;
struct node { node employeeData; struct node *next; }; // struct node
struct node *head, *z, *t;
initializeList ( node employeeData, FILE *data ) // initialize list function
{
head = ( node * ) malloc( sizeof *head );
z = ( node * ) malloc( sizeof *z );
head->next = z;
z->next = z;
}
int main (void)
{
data = fopen( "empInfo.txt","r" );
node employeeData = {0,0,0,0,0};
while (getchar () != '\n')
getchar ();
fclose( data );
return 0;
}
Is this a correct implementation of this? Very new to programming so please be easy on me. My assignment is no where near done so I am aware that it doesn't really do anything right now.

Keep segfaulting when trying to pass struct into function

I'm trying to pass a pointer to a queue into the createQueue function:
void createQueue(struct pqueue *queue){
queue = malloc( sizeof(struct pqueue) );
queue->root = malloc(sizeof(struct node));
queue->root->next = 0;
queue->root->taskID = 12;
queue->root->priority = 5000;
}
I also try to add to the newly created queue like this:
void add(struct pqueue *queue, int taskID, int priority){
struct node *conductor;
conductor = queue->root;
if ( conductor != 0 ) {
while ( conductor->next != 0)
{
conductor = conductor->next;
}
}
conductor->next = malloc( sizeof(struct node) );
conductor = conductor->next;
if ( conductor == 0 )
{
printf( "Out of memory" );
}
/* initialize the new memory */
conductor->next = 0;
conductor->taskID = taskID;
conductor->priority = priority;
}
from the main function:
int main()
{
struct pqueue *queue;
createQueue(queue);
add(queue, 234093, 9332);
}
...but I keep segfaulting. Any reason why this keeps happening?
EDIT:
The structs for pqueue and node are like this:
struct node {
int taskID;
int priority;
struct node *next;
};
struct pqueue{
struct node *root;
};
In C, everything is passed by value. Therefore, when you call createQueue(queue), you are passing a copy of the pointer to the function. Then, inside the function, when you say queue = malloc(...), you are setting that copy of the pointer equal to your newly allocated memory - leaving main()'s copy of that pointer unchanged.
You want to do something like this:
void createQueue(struct pqueue **queue)
{
(*queue) = malloc( ... );
}
int main(void)
{
struct pqueue *queue;
createQueue(&queue);
}
This question has a more detailed description of what's going wrong for you.

Resources