I am trying to write a function, which is deleting a specific element from my linked list, but it crash with segmentation fault when I reach the element. Here is a part of my code
typedef struct dlist_t {
int data;
struct dlist_t *prev, *next;
} dlist_t;
typedef struct list_t {
dlist_t *head, *tail;
} list_t;
int delElement(list_t *list, int elem) {
while (list) {
if ((list->head)->data == elem) {
list->head->next = list->head->prev;
list->head->prev = list->head->next;
free(list);
return 1;
}
list = list->head->next;
}
return 0;
}
Your function definition does not make sense. For example in this assignment statement
list = list->head->next;
there are used objects of different types in the left hand side of the assignment (the type is list_t
) and in the right hand side of the assignment (the type is dlist_t
).
Or this call
free(list);
tries to free the list instead of only its one node. And so on.
The function can look the following way as it is shown in thje demonstrative program below.
#include <stdio.h>
#include <stdlib.h>
typedef struct dlist_t
{
int data;
struct dlist_t *prev, *next;
} dlist_t;
typedef struct list_t
{
dlist_t *head, *tail;
} list_t;
int delElement( list_t* list, int elem )
{
dlist_t **current = &list->head;
while ( *current != NULL && ( *current )->data != elem )
{
current = &( *current )->next;
}
int success = *current != NULL;
if ( success )
{
dlist_t *tmp = *current;
if ( ( *current )->next != NULL )
{
( *current )->next->prev = ( *current )->prev;
}
else
{
list->tail = ( *current )->prev;
}
*current = ( *current )->next;
free( tmp );
}
return success;
}
int pushFront( list_t *list, int elem )
{
dlist_t *new_node = malloc( sizeof( dlist_t ) );
int success = new_node != NULL;
if ( success )
{
new_node->next = list->head;
new_node->prev = NULL;
new_node->data = elem;
if ( list->head != NULL )
{
list->head->prev = new_node;
}
else
{
list->tail = new_node;
}
list->head = new_node;
}
return success;
}
int pushBack( list_t *list, int elem )
{
dlist_t *new_node = malloc( sizeof( dlist_t ) );
int success = new_node != NULL;
if ( success )
{
new_node->prev = list->tail;
new_node->next = NULL;
new_node->data = elem;
if ( list->tail != NULL )
{
list->tail->next = new_node;
}
else
{
list->head = new_node;
}
list->tail = new_node;
}
return success;
}
void printList( list_t *list )
{
for ( dlist_t *current = list->head; current != NULL; current = current->next )
{
printf( "%d -> ", current->data );
}
puts( "null" );
}
void printReverseList( list_t *list )
{
for ( dlist_t *current = list->tail; current != NULL; current = current->prev )
{
printf( "%d -> ", current->data );
}
puts( "null" );
}
int main(void)
{
list_t list = { .head = NULL, .tail = NULL };
const int N = 10;
for ( int i = 0; i < N; i++ )
{
if ( i % 2 == 0 ) pushFront( &list, N / 2 - i / 2 - 1 );
else pushBack( &list, N / 2 + i / 2 );
}
printList( &list );
printReverseList( &list );
putchar( '\n' );
for ( size_t i = 0; i < N; i++ )
{
if ( i % 2 == 0 ) delElement( &list, i / 2 );
else delElement( &list, N - i / 2 - 1 );
printList( &list );
printReverseList( &list );
putchar( '\n' );
}
return 0;
}
The program output is
0 -> 1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7 -> 8 -> 9 -> null
9 -> 8 -> 7 -> 6 -> 5 -> 4 -> 3 -> 2 -> 1 -> 0 -> null
1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7 -> 8 -> 9 -> null
9 -> 8 -> 7 -> 6 -> 5 -> 4 -> 3 -> 2 -> 1 -> null
1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7 -> 8 -> null
8 -> 7 -> 6 -> 5 -> 4 -> 3 -> 2 -> 1 -> null
2 -> 3 -> 4 -> 5 -> 6 -> 7 -> 8 -> null
8 -> 7 -> 6 -> 5 -> 4 -> 3 -> 2 -> null
2 -> 3 -> 4 -> 5 -> 6 -> 7 -> null
7 -> 6 -> 5 -> 4 -> 3 -> 2 -> null
3 -> 4 -> 5 -> 6 -> 7 -> null
7 -> 6 -> 5 -> 4 -> 3 -> null
3 -> 4 -> 5 -> 6 -> null
6 -> 5 -> 4 -> 3 -> null
4 -> 5 -> 6 -> null
6 -> 5 -> 4 -> null
4 -> 5 -> null
5 -> 4 -> null
5 -> null
5 -> null
null
null
Play with the program and playing investigate it.
Do not forget to write yourself the function that frees all allocated nodes in the list.